Я не могу понять достойный титул - отредактируйте его, если у вас есть лучшее описание. Надеюсь, кто-то может помочь мне понять, что происходит. У меня есть следующий код, который я только что скомпилировал на linux - он работает. Я просто не понимаю, как, когда я вызываю Foo
с помощью const char*
, его бросает (компилятор?) В объект Object Test
.
#include <iostream>
#include <cstring>
class Test
{
public:
Test(const char* _data = "")
{
int length = strlen(_data);
internalData = new char[length+1];
strncpy(internalData, _data, length);
internalData[length] = '\0';
}
char* internalData;
};
class Bar
{
public:
void Foo(Test _data)
{
std::cout << "Data: " << _data.internalData << std::endl;
}
};
int main(int argc, char* argv[])
{
Bar b;
b.Foo("This is my data");
}
// Output: Data: This is my data
Итак, мне любопытно, почему/как это работает - это компилятор? во время выполнения? Есть ли документация о том, почему - что кто-то может предоставить ссылку?
Компилятор должен искать правильное преобразование из char const*
в Test
, поэтому он ищет конструкторы из Test
для преобразования аргумента. Это стандартное поведение, разрешенное в §12.3/1 (акцент мой):
Тип преобразования объектов класса может быть задан конструкторами и функциями преобразования. Эти преобразования называются пользовательскими преобразованиями и используются для неявных преобразований типов (раздел 4), для инициализации (8.5) и для явных преобразований типов (5.4, 5.2.9).
Неявная последовательность преобразований создает временный экземпляр Test
который затем копируется или перемещается в параметр. Эта копия/перемещение действительно может быть устранена компилятором с помощью оптимизации, известной как copy-elision.
Если вы хотите предотвратить неявные преобразования, вы можете отметить свой конструктор explicit
:
explicit Test(char const* = "");
b.Foo("This is my data");
->b.Foo(Test("This is my data"))
std::string
чтобы вам не приходилось беспокоиться об утечке памяти.