Как я могу вызвать конструктор копирования для членов данных?

Я попробовал это:

class cls1{
public:
cls1(){ cout << "cls1 constructor\n";}
cls1 (cls1 & o){ cout << "cls1 copy constructor\n";}
};

class cls2{
public:
cls2 () { cout << "cls2 constructor\n";}
cls2 (cls2 & o){ cout << "cls2 copy constructor\n";}
};

class my_cls{
public:
cls1 o1;
cls2 o2;
my_cls(){ cout << "my_cls constructor\n";}
my_cls(my_cls& o){ cout << "my_cls copy constructor\n";}
};

void f(my_cls o){}

int main(){
my_cls p;
f(p);
return 0;
}

но вывод:

cls1 constructor
cls2 constructor
my_cls constructor
cls1 constructor
cls2 constructor
my_cls copy constructor

Я нахожу это странным, так как мне сказали, что для каждого члена конструктор копирования вызывает конструктор копирования для этого члена, за исключением типов примитивов, когда делается побитовая копия. (Я ожидал, что конструкторы копирования cls1 и cls2 будут вызываться перед конструктором копирования my_cls)

1

Решение

На самом деле:

der (der & o){ cout << "my_cls copy constructor\n";}

эквивалентно

der (der & o):o1(),o2(){ cout << "my_cls copy constructor\n";}

т. е. ваш конструктор копирования вызывает конструктор по умолчанию ваших членов класса.

Чтобы заставить его вести себя как ожидалось:

der (der & o):o1(o.o1),o2(o.o2){ cout << "my_cls copy constructor\n";}

Чтобы сделать это семантически правильным:

der (der const& o)
1

Другие решения

То, что вам сказали, верно только для конструктора копирования, сгенерированного компилятором.

Если вы хотите написать свой собственный конструктор копирования, вам нужно поместить c-tors членов и базовых классов в список инициализации, иначе будут использоваться их c-tors по умолчанию.

В вашем примере отсутствуют : o1(o.o1), o2(o.o2):

der (der & o)
: o1(o.o1)
, o2(o.o2)
{ cout << "my_cls copy constructor\n";}
5

Это похоже на список инициализации обычного конструктора

class my_cls{
public:
cls1 o1;
cls2 o2;
my_cls (){ cout << "my_cls constructor\n";}
my_cls (my_cls & o) : o1(o.o1), o2(o.o2) { cout << "my_cls copy constructor\n";}
};
1