C++ 关于默认和复制构造函数
考虑以下代码:C++ 关于默认和复制构造函数,c++,inheritance,copy-constructor,C++,Inheritance,Copy Constructor,考虑以下代码: #include <iostream> struct A { A() {} // Can't be commented A( const A& other ) =delete; int i; }; struct B : public A { B( int j ) { this->i = j; } B( const B& other ) { this->i = other.i; } }; int
#include <iostream>
struct A
{
A() {} // Can't be commented
A( const A& other ) =delete;
int i;
};
struct B : public A
{
B( int j ) { this->i = j; }
B( const B& other ) { this->i = other.i; }
};
int main()
{
B b(42);
std::cout << b.i << std::endl;
}
#包括
结构A
{
无法对A(){}//进行注释
A(常数A和其他)=删除;
int i;
};
结构B:公共A
{
B(intj){this->i=j;}
B(constb&other){this->i=other.i;}
};
int main()
{
B(42);
std::cout因为此构造函数:
B( int j ) { this->i = j; }
默认情况下初始化B
的A
子对象。它执行与此等效的操作:
B( int j ) : A() { this->i = j; }
因为A
有一个用户声明的非默认构造函数(即使它被声明为已删除
),编译器不会为您合成默认构造函数。因此您需要自己提供它。如果您至少声明了一个非默认构造函数,编译器将不会为您生成默认构造函数。如果您想一想,这实际上是有意义的。想象一下,创建一个类时不需要将某些值传递给在这种情况下,即使您尝试了多少次,也无法创建空构造函数
当您注释掉A的空构造函数时,B的构造函数将无法调用它
当您注释掉这两个构造函数时,编译器认为可以为复制构造函数和空构造函数生成默认实现。一旦您在类中声明了一个构造函数(并且声明了一个已删除的构造函数,他只是…已删除),编译器将不再为您生成任何默认构造函数
所以,若你们注释掉了默认构造函数,你们就并没有为类A留下任何可以被B的构造函数使用的构造函数了(因为B的构造函数在B内部进行A部分的默认初始化)。它也不能调用A的默认构造函数(因为并没有!)而且代码格式不正确。我不是投反对票的人,对此表示抱歉。但这并不能真正回答我的问题;如果我在A中注释两个构造函数,那么我就可以编译了。因此我的问题是“当我禁用其复制构造函数时会有什么变化”?我个人认为你的答案是好的,也没有理由投反对票。但是删除构造函数是否算作一个定义呢?@LuchianGrigore是的,你是对的。我已经纠正了这个说法。@Sh3ljohn正如下面juanchopanza和上面我的回答所指出的,问题实际上是B的构造函数隐式地调用了@Sh3ljohn:它算作一个声明。这个答案中的术语有点不可靠-你只需要声明(而不是定义)一个构造函数来禁止隐式的默认构造函数。@MikeSeymour感谢你的精度:)”只要你在类中声明一个构造函数(声明了一个已删除的构造函数,他只是…已删除),编译器不会为您生成任何其他构造函数。”-错误。确实存在移动构造函数。我忘记了编辑答案。