C++构造函数和初始化器行为。这5个代码有什么区别?
我是新来的c + +编程语言。我编写了几种代码模式来理解C++构造函数和初始化函数。但我找不到为什么一个构建失败,另一个没有。在我看来,似乎没有这样的区别,一个失败,另一个不失败。代码是以下5个代码。代码示例1-2,2-3,3-4,4-5之间有什么区别。为什么一个失败,但另一个不失败?C++构造函数和初始化器行为。这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(){
}
有例如2没有错误,因为你不尝试构建B
。如果添加到主B b;
那么你会得到这样的错误
error: use of deleted function 'B::B()'
的原因您尝试实例化一个B
是因为A a;
只是一个成员声明之前,你没有得到一个错误。直到构造函数被调用并且你试图实例化a
,你发现它不是默认可构造的。
例3基本上是一样的东西。既然您正在定义一个构造函数,编译器会自动添加a
的默认初始值,因为您没有在成员初始值设定项列表中提供一个。当它看到A
不是默认可构造的,因此它发出错误。因为你指定了如何构建a
例4不会失败。既然你这样做了,编译器不会尝试默认构造它,而是用你提供的值构造a
。
例5再次失败,因为例3同样的原因,试图将默认初始化添加到成员初始化列表,但不能因为它不存在,这给你的错误。
你似乎已经掌握了大部分这一切,所以让我通读一切并澄清。
示例1:您正在尝试创建A实例而未提供所需的构造函数参数。
示例2:类B
无法实例化,因为它需要创建A
的实例,并且您尚未指定将哪些参数发送给其构造函数。如果您要在某处创建B
的实例,那么您会在此处收到编译器错误。例如在main()中放入B b;
。
示例3:构造函数B::B(int)
无法编译,因为您尚未为构造函数B::a
(其实例A
)指定有效参数。你在这里得到错误,因为在这个构造函数中,你必须指定一个```的参数。
例4:在这里,您要在初始化列表B::B
中指定哪些参数应该传递给B::a
。这是你需要做的,以便它进行编译。
示例5:此处您试图指定值为123
。这是在构造函数B::B
的主体中完成的,它在B
的所有成员都被初始化后调用。它没有指定参数为a
的构造函数。它只是试图在它已经被构建之后为它分配一个新的值。既然你不指定应发送到的a
构造函数的值,你得到同样的错误与例3
这帮了很多。我多次阅读你的答案和@ NathanOliver。最后我得到了它。谢谢。 –
- 1比2:例2不失败,因为你永远不实例
B
ØA
在主 - 2比3:3例失败,因为在你的
B
构造你不打电话给A::A()
和A
没有默认构造函数 - 3比4:例4,因为你打电话不失败
A::A()
在您的B
构造函数中。 - 4 vs 5:示例5失败,因为(再次)您不调用
A::A()
而A
没有默认构造函数。但是123
可以asigned到A
(因为隐式声明的拷贝赋值运算符声明,和你有一个构造函数建立从int
的A
)
很简单,我喜欢这个。当我困惑时,我一次又一次地回答这个问题。谢谢。 –
我忘了说,我想你最后提到的'a = 123'可以在没有演员的情况下创建A的实例。 –
@KeiMinagawa你是完全正确的,在这种情况下是可以的,因为声明了隐式声明的复制赋值操作符,并且你有一个构造函数来从'int'构建'A'。编辑我的答案。 – Rama
我觉得这是非常细节和一个什么样的精确描述发生在这些例子中。谢谢。 –
@KeiMinagawa没问题。乐意效劳。 – NathanOliver