为了账号安全,请及时绑定邮箱和手机立即绑定

含有对象的拷贝构造函数及其初始化列表

http://img1.sycdn.imooc.com//562ae23b00012b0b05230467.jpg

运行时系统会有:


http://img1.sycdn.imooc.com//562ae2c6000154c209370531.jpg

正在回答

4 回答

直接在你的评论下回复有字数限制,我再发一条回答好了。

你前一次的错误是缺少函数定义,根本不能编译。

这次加上base的默认构造函数后,可以编译并运行了。


但如果你只是加上base的默认构造函数,没有改别处的话,那这次的错误就在于:

Big的拷贝构造函数还是没有做任何事! 且不说它并没有拷贝a1的内容,甚至也没有初始化自己的成员变量。 这种情况下,Big的成员变量会被默认初始化:也即是int v被默认初始化为随机值;base b就调用了自己的默认构造函数,这样b.k就是0(前一次就因为没有base的默认构造函数,所以在这里编译失败)

所以第二行输出的内容最后是一个0(a2.b.k),前面那一大串就是a2.v中的随机值。

0 回复 有任何疑惑可以回复我~
#1

qq_阳光下的海风_0 提问者

非常敬佩老师认真负责的态度
2015-10-26 回复 有任何疑惑可以回复我~
#2

qq_阳光下的海风_0 提问者

哦哦哦,我想我可能没有理解透自己定义的默认构造函数和系统默认的构造函数吧。 刚刚我用注释掉拷贝构造函数,运行的到预期的结果, 所以,可以这样理解自己定义的默认构造函数和系统默认的构造函数吧:自己定义的默认构造函数在某种方面来说是“静态”的,你想让它干什么,他就可以干什么,但是它不会随着整个程序内容的特殊而改变,而系统默认的构造函数可以说是“动态”的,随着需求的改变而改变。 可以这样理解吗,老师?
2015-10-26 回复 有任何疑惑可以回复我~
#3

onemoo 回复 qq_阳光下的海风_0 提问者

这里你说的“系统默认的构造函数”是编译器自动生成的拷贝构造函数。 当你没有定义拷贝构造函数时,编译器会自动生成一个拷贝构造函数,它的行为仅仅是简单地拷贝将所有的成员变量。 Big::v是个内置int类型,进行简单的拷贝没有问题。 Big::b是base类型,对它进行拷贝会调用base的拷贝构造函数。 你也没有定义base的拷贝构造函数,同样编译器为base生成了一个,也仅仅是将base::k进行拷贝,这也没有问题。 所以最终代码能得到正确的结果。 复杂一些的类在拷贝时就不能仅仅简单地复制成员变量了,这时就不能依赖编译器自动生成的拷贝构造函数了,需要你自己实现一个。
2015-10-27 回复 有任何疑惑可以回复我~
#4

qq_阳光下的海风_0 提问者 回复 onemoo

老师,我的编译器真的可以用默认拷贝构造函数的。 由于字数限制,就只好回复在评论下了
2015-10-28 回复 有任何疑惑可以回复我~
#5

onemoo 回复 qq_阳光下的海风_0 提问者

诶,我没说不可以啊! 仔细读读我上个回答的第二行,也分析了为什么系统自动生成的拷贝构造函数可以应用于Big类。 最后还指出了自动生成的拷贝构造函数的局限性。
2015-10-29 回复 有任何疑惑可以回复我~
查看2条回复
 onemoo:class base
{
public:
    int k;
    base(int n):k(n) {}
    //base(){}

};
class Big
{


public:
    int v;
    base b;

     Big(int n=0):v(n),b(n){}
     //Big(const Big &c):v(c.v),b(c.b){}
     //Big(const Big &c){v=c.v;b=c.b;}//没有拷贝构造函数也可以
};
int main()
{
    Big a1(5);
    Big a2=a1;
    cout<<a1.v<<a1.b.k<<endl;
    cout<<a2.v<<a2.b.k<<endl;
    return 0;
}
可能是编译器的原因吧,我这个可以呀
运行结果是正确的


0 回复 有任何疑惑可以回复我~
#1

onemoo

确实可以啊。 我前面的回答中说了“当你没有定义拷贝构造函数时,编译器会自动生成一个拷贝构造函数,它的行为仅仅是简单地拷贝将所有的成员变量。” 也说了,Big中的成员变量都可以进行拷贝,所以是可以编译通过的。
2015-10-29 回复 有任何疑惑可以回复我~
#2

qq_阳光下的海风_0 提问者 回复 onemoo

我是想说运行结果也是对的。
2015-10-29 回复 有任何疑惑可以回复我~
#3

onemoo 回复 qq_阳光下的海风_0 提问者

哦,对。 因为这两个类都很简单,把每个成员变量都复制一遍就可以完成拷贝,正好和系统自动生成的拷贝构造函数的行为一样,所以你使用自动生成的拷贝构造函数也不会有问题。 只是复杂的类就不一定能用自动生成的拷贝构造函数了。
2015-10-30 回复 有任何疑惑可以回复我~

562cd61e000146ef04980416.jpg

http://img1.sycdn.imooc.com//562cd6340001fd6b06580424.jpg

我试了一下给base类定义了默认构造函数,可是,从运行的结果来看,在拷贝构造函数那里还是出错了!

请帮我看看,哪里有问题?


0 回复 有任何疑惑可以回复我~

你定义了Big的拷贝构造函数,但它的函数体中是空的,也就是这个函数不做任何事。

Big a2 = a1; 这句需要拷贝构造Big,而Big的拷贝构造函数没有把成员变量base b初始化。那么b会调用自己的默认构造函数,可是base类唯一的一个构造函数是 base(int n),你没有定义base的默认构造函数! 


所以解决方法是:

要么为base类定义一个默认构造函数。 

要么在Big(const Big &c)中用构造初始化列表的方式调用base的构造函数。

0 回复 有任何疑惑可以回复我~
#1

qq_阳光下的海风_0 提问者

我试了一下给base类定义了默认构造函数,可是,从运行的结果来看,在拷贝构造函数那里还是出错了! 请帮我看看,哪里有问题? 因为回复时不能添加图片,所以麻烦您到我对自己的评论上看下。感激不尽
2015-10-25 回复 有任何疑惑可以回复我~

举报

0/150
提交
取消
C++远征之封装篇(上)
  • 参与学习       103410    人
  • 解答问题       701    个

封装--面向对象的基石,本教程力求帮助小伙伴们即学即会

进入课程

含有对象的拷贝构造函数及其初始化列表

我要回答 关注问题
意见反馈 帮助中心 APP下载
官方微信