我对c++编程语言很陌生。我编写了几种代码模式来理解c++构造函数和初始化器。但我不知道为什么一个构建失败,另一个构建失败。在我看来,似乎没有这样的区别,一个失败和另一个失败。代码是以下5个代码。代码示例1-2,2-3,3-4,4-5之间有什么区别?为什么一个失败而另一个失败?
Additional Info: --我正在用Xcode 8.2构建这些代码。
代码
示例1:
class A{
public:
A(int xxx) { }
};
int main(){
A a; // Fail here. I see this is because there is no default constructor in definition of class A.
}示例2:
class A{
public:
A(int xxx) { }
};
class B{
public:
A a; // No fail. Why? I supposed it will fail like Example 1.
};
int main(){
}例3:
class A{
public:
A(int xxx) { }
};
class B{
public:
A a; // No fail here.
B(int xxx) { } // But fail here. Why? I just added constructor to Example 2.
};
int main(){
}例4:
class A{
public:
A(int xxx) { }
};
class B{
public:
A a;
B(int xxx) : a(123) { } // No fail. Why Just adding ":a(123)" works.
};
int main(){
}例5:
class A{
public:
A(int xxx) { }
};
class B{
public:
A a;
B(int xxx){ a = 123; } // Fail again. Why? I think ":a(123)" and "a=123" is same meaning.
};
int main(){
}发布于 2017-03-22 13:46:18
没有错误(例如,2),因为您从未尝试构造B。如果将其添加到主B b;中,则会得到以下错误
错误:使用已删除的函数'B::B()‘
在尝试实例化B之前没有收到错误的原因是因为A a;只是一个成员声明。直到调用构造函数并尝试实例化a之后,才发现它不是默认的可构造结构。
例3基本上是一样的。既然您正在定义构造函数,编译器将自动向其添加a的默认初始化,因为您没有在成员初始化程序列表中提供默认初始化。当它看到A不是默认的可构造的,所以它会发出错误。
示例4不会失败,因为您指定了如何构造a。由于您这样做了,编译器将不会尝试默认构造它,而是使用您提供的值构造a。
示例5由于示例3中相同的原因再次失败,它试图将默认初始化添加到成员初始化列表中,但由于它不存在,所以不能这样做,这会导致错误。
发布于 2017-03-22 13:51:50
你似乎掌握了这其中的大部分诀窍,所以让我把它们全部讲清楚。
示例1:您试图创建一个A的实例,而不提供它需要的构造函数参数。
示例2:类B无法实例化,因为它需要创建一个A实例,而且您还没有指定要发送给它的构造函数的参数。如果要在某个地方创建B实例,将在这里得到一个编译器错误。例如,将B b;放在main()中。
示例3:构造函数B::B(int)无法编译,因为您没有为B::a的构造函数(它的A实例)指定有效的参数。这里出现了错误,因为这是在构造函数期间,因此必须为指定参数。
示例4:在B::B的初始化列表中指定应该传递给B::a的参数。为了让它编译,您需要这样做。
示例5:这里您正在尝试分配一个123的值。这是在构造函数B::B的主体中完成的,在初始化了B的所有成员之后调用该构造函数。它没有为a的构造函数指定参数。它只是试图在它已经被构造之后给它分配一个新的值。由于您没有指定应该发送给a构造函数的值,所以您将得到与示例3相同的错误。
发布于 2017-03-22 14:21:28
B o AB构造函数中不调用A::A(),A没有默认构造函数A::A()构造函数中调用了B。A::A(),而且A没有默认的构造函数。但是123可以被签名到A (因为隐式声明的拷贝赋值操作符是声明的,并且您有一个构造函数可以从int构建A )。https://stackoverflow.com/questions/42953299
复制相似问题