Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 关于默认和复制构造函数_C++_Inheritance_Copy Constructor - Fatal编程技术网

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感谢你的精度:)”只要你在类中声明一个构造函数(声明了一个已删除的构造函数,他只是…已删除),编译器不会为您生成任何其他构造函数。”-错误。确实存在移动构造函数。我忘记了编辑答案。