Должны ли мы явно написать конструктор копирования, если член класса является вектором? - PullRequest
7 голосов
/ 25 января 2012
struct myType {
    vector<char*> ls;
};

Здесь ls содержит указатели на char.Если пользовательский конструктор копирования для myType не указан, будет ли конструктор копирования по умолчанию myType делать глубокое копирование ls?

Ответы [ 3 ]

8 голосов
/ 25 января 2012

Здесь ls держит указатель на символ. Если конструктор копирования не указан, будет ли конструктор копирования по умолчанию выполнять глубокое копирование?

Конструктор копирования по умолчанию будет копировать все элементы - то есть вызывать их соответствующие конструкторы копирования. 1 Так что да, std::vector (ничего особенного в отношении C ++) будет должным образом скопировано.

Однако память, на которую указывают элементы char* внутри вектора, конечно же, не будет, поскольку C ++ не знает и не заботится о том, на что указывают указатели.

Но решение здесь не в том, чтобы предоставить пользовательский конструктор копирования. Для этого нужно использовать структуру данных вместо необработанных указателей (char*) . И это бывает std::string (или std::vector<char> в зависимости от намерения).


1 Таким образом, создавая транзитивное замыкание операции копирования - так обычно применяется глубокое копирование, но, конечно, разработчик операции копирования всегда может выйти из него .

8 голосов
/ 25 января 2012

будет ли конструктор копирования по умолчанию делать глубокое копирование?

Конечно, нет.Компилятор не может знать, кому принадлежит указанная память.

Если требуется глубокое копирование, необходимо реализовать конструктор копирования и вручную скопировать каждый char* в новую память для vector в скопированнойна object.

Если вы используете char* в качестве строк с нулевым символом в конце, то вам действительно следует использовать std::string.Если вы это сделаете, достаточно конструктора по умолчанию.

2 голосов
/ 25 января 2012

Нет, не будет.

C ++ будет рекурсивно вызывать копию ctor всех подобъектов.Таким образом, он будет вызывать копию ctor вектора, который, в свою очередь, будет вызывать копию ctor char*, которая будет копировать char* по значению.C ++ никогда не будет автоматически выделять память и копировать данные.Он даже не может этого сделать, так как не знает, на какие данные вы указываете и сколько их следует копировать.

Когда вы используете строки, вы должны предпочесть использовать std::string, так какэто сделает все копирование за вас.Если это какой-то буфер двоичных данных, который требует специальной обработки, то вам нужно сделать это самостоятельно в своем копирующем ctor (и когда вы закончите, подумайте, действительно ли разумно подумать о том, чтобы C ++ сделал это за вас).

Когда вы пишете свой собственный ctor, вы всегда должны помнить о Правиле Трех

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...