указатель на символ функции c ++ и строка - PullRequest
4 голосов
/ 19 февраля 2012
void callme(string a)
{
  cout<<"STRING CALLED"<<endl;
}

void callme(char * a)
{
  cout<<"char pointer called"<<endl;
}

int main()
{
   callme("ASDADS");
   return 0;
}

почему именно так будет называться char*?и почему, когда я закомментирую функцию с параметром char*, будет вызвана другая функция?

Ответы [ 4 ]

4 голосов
/ 19 февраля 2012

Это потому, что "ASDADS" конвертируется в char *.Таким образом, компилятор генерирует код для первой функции, которой он может соответствовать аргумент.

Если вы удалите прототип с char *, компилятор будет искать функции, которые принимают параметр с неявным приведением из char *к типу параметра.

Возьмем, к примеру, следующее:

class A
{
public:
    A() {}
    A(int x) {}
};

//void foo(int x) {}
void foo(A x) {}

int main(int argc, char* argv[])
{
    int x = 3;
    foo(x);
}

если вы закомментируете foo(int x), будет вызвана другая функция.если вы объявите конструктор как explicit, вы получите ошибку:

class A
{
public:
    A() {}
    explicit A(int x) {}
};
3 голосов
/ 19 февраля 2012

Тип строкового литерала (например, "abc") - это "массив константных символов". Однако, как специальное правило, C ++ допускает (не рекомендуется!) Стандартное преобразование в char *. Такое преобразование предпочтительнее пользовательского преобразования, предоставляемого конструктором string::string(const char *). Таким образом, перегрузка char* выигрывает при разрешении перегрузки (ноль пользовательских преобразований для char*, а не одно пользовательское преобразование для string).

(Я не могу найти стандартную ссылку для этого; напротив, C.1.1 явно говорит, что char * p = "abc"; «недопустим в C ++». Любой дальнейший ввод приветствуется. Редактировать: Похоже, что это изменение с C ++ 03 на C ++ 11, а в C ++ 11 это совершенно нелегально.)

0 голосов
/ 19 февраля 2012

По умолчанию на «ASDADS» ссылается указатель на символ.Поэтому используется вторая версия callme ().Если это закомментировано, компилятор попытается сопоставить его со строкой, и, следовательно, используется 1-я версия callme ().

0 голосов
/ 19 февраля 2012

Когда у вас есть обе функции, есть две альтернативы на выбор, и (char *) лучше соответствует вашему аргументу "ASDADS". Если вы удалите функцию (char *), тогда будет одна функция, которая хочет строку. Таким образом, компилятор создает строку, используя строковый конструктор, который принимает символ *.

http://www.cplusplus.com/reference/string/string/string/

...