Рассмотрим иерархию классов, где A
является базовым классом, а B
- A
.Почему конструктор неявных копий вызывает конструктор копирования базового класса и не имеет определенного конструктора копирования?
Если конструктор копирования не определен в B
, компилятор его синтезирует. При вызове этот конструктор копирования вызывает конструктор копирования базового класса (даже синтезированный, если ни один из них не был предоставлен пользователем).
#include <iostream>
class A {
int a;
public:
A() {
std::cout << "A::Default constructor" << std::endl;
}
A(const A& rhs) {
std::cout << "A::Copy constructor" << std::endl;
}
};
class B : public A {
int b;
public:
B() {
std::cout << "B::Default constructor" << std::endl;
}
};
int main(int argc, const char *argv[])
{
std::cout << "Creating B" << std::endl;
B b1;
std::cout << "Creating B by copy" << std::endl;
B b2(b1);
return 0;
}
Выход:
Creating B
A::Default constructor
B::Default constructor
Creating B by copy
A::Copy constructor
Если пользователь определяет свой собственный конструктор копирования в B
, когда вызывается этот конструктор копирования не будет вызывать конструктор базового класса по умолчанию, если вызов конструктор копии базового класса явно присутствует (например, в списке инициализации).
#include <iostream>
class A {
int a;
public:
A() {
std::cout << "A::Default constructor" << std::endl;
}
A(const A& rhs) {
std::cout << "A::Copy constructor" << std::endl;
}
};
class B : public A {
int b;
public:
B() {
std::cout << "B::Default constructor" << std::endl;
}
B(const B& rhs) {
std::cout << "B::Copy constructor" << std::endl;
}
};
int main(int argc, const char *argv[])
{
std::cout << "Creating B" << std::endl;
B b1;
std::cout << "Creating B by copy" << std::endl;
B b2(b1);
return 0;
}
Выход:
Creating B
A::Default constructor
B::Default constructor
Creating B by copy
A::Default constructor
B::Copy constructor
Мой вопрос, почему не определяется пользователем конструктор копирования вызвать конструктор копирования базового класса, как поведение по умолчанию?
Если бы это было так по умолчанию, как бы вы указали случай, когда вы не хотите, чтобы это произошло? – PlasmaHH
@PlasmaHH 'ParentClass()' в списке инициализаторов. По-моему, это все равно было бы непоследовательным и запутанным. –
@MarkB: Действительно, я надеялся, что он придет к такому же выводу, подумав об этом ... – PlasmaHH