首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >c++构造函数和初始化器行为。这五个密码有什么区别?

c++构造函数和初始化器行为。这五个密码有什么区别?
EN

Stack Overflow用户
提问于 2017-03-22 13:38:16
回答 3查看 96关注 0票数 0

我对c++编程语言很陌生。我编写了几种代码模式来理解c++构造函数和初始化器。但我不知道为什么一个构建失败,另一个构建失败。在我看来,似乎没有这样的区别,一个失败和另一个失败。代码是以下5个代码。代码示例1-2,2-3,3-4,4-5之间有什么区别?为什么一个失败而另一个失败?

Additional Info: --我正在用Xcode 8.2构建这些代码。

代码

示例1:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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(){

}
EN

回答 3

Stack Overflow用户

发布于 2017-03-22 13:46:18

没有错误(例如,2),因为您从未尝试构造B。如果将其添加到主B b;中,则会得到以下错误

错误:使用已删除的函数'B::B()‘

在尝试实例化B之前没有收到错误的原因是因为A a;只是一个成员声明。直到调用构造函数并尝试实例化a之后,才发现它不是默认的可构造结构。

例3基本上是一样的。既然您正在定义构造函数,编译器将自动向其添加a的默认初始化,因为您没有在成员初始化程序列表中提供默认初始化。当它看到A不是默认的可构造的,所以它会发出错误。

示例4不会失败,因为您指定了如何构造a。由于您这样做了,编译器将不会尝试默认构造它,而是使用您提供的值构造a

示例5由于示例3中相同的原因再次失败,它试图将默认初始化添加到成员初始化列表中,但由于它不存在,所以不能这样做,这会导致错误。

票数 4
EN

Stack Overflow用户

发布于 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相同的错误。

票数 2
EN

Stack Overflow用户

发布于 2017-03-22 14:21:28

  • 1vs2:示例2不要失败,因为您从未在主程序中实例化B o A
  • 2 vs 3:示例3失败,因为在您的B构造函数中不调用A::A()A没有默认构造函数
  • 3vs4:示例4不会失败,因为在您的A::A()构造函数中调用了B
  • 4 vs 5:示例5失败,因为(再次)您没有调用A::A(),而且A没有默认的构造函数。但是123可以被签名到A (因为隐式声明的拷贝赋值操作符是声明的,并且您有一个构造函数可以从int构建A )。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42953299

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档