当没有编写时,编译器一定会生成拷贝构造函数,赋值函数 吗?

一般说来,C++ 编译器会为我们生成四个函数,默认构造函数,析构函数,拷贝构造函数,赋值函数,如果我们没有声明它们的话。

但情况真的是这样的吗?不,这不是永恒的真理!

首先,明确一点,上面的函数没有声明时,编译器只在认为它们有必要被创建时才去创建,具体而言:

对于构造函数:

只有以下四种情况下会合成默认构造函数(且只会在需要被调用时才合成):

1.某一个成员含有constructor,不论这个函数是用户自己写的,还是编译器生成的。因为编译器必须生成一个构造函数并在里面安放调用那个成员的构造函数的代码,如果有多个成员, 则以它们的声明顺序去调用。

class B

{

char *str;//初始化这个变量不是编译器的事情,不会在合成的构造函数里面初始化它。

Foo foo;

B() //如果不存在任何构造函数,则会生成下面这个构造函数

{

foo.Foo::Foo(); //安插 foo 的构造代码

}

//如果用户定义了构造函数,则会在每个已定义的构造函数里面,安插 foo 的构造代码

}

2.类的基类带有 constructor ,不论这个函数是用户自己写的,还是编译器生成的。编译器必须生成一个构造函数并在里面安放调用基类的构造函数的代码(比调用成员的构造函数要早)。

不再举例,与 1 类似。

3.带有一个 virutual Function ,此时,这个类需要保存一个虚表指针 pvtbl 用于指向虚函数表 vtbl,vtbl 里面存放的是各个虚函数的函数指针。pvtbl 暗含在类中,它在构造函数最开始的地方被初始化指向那个 vtbl。

4.带有一个 "Virtual Base Class"的 class,如菱形继承

class X{ int i; };

class A : public virtual X{};

class B : public virtual X{};

class C : public A,public B{};

在这个继承体系中,如果有这样的代码:

A * pa;

pa -> i = 1;

则 pa -> i 的这个数据必须要在运行时,才能决议出它的地址,因为 A* 的动态类型可能是 C,在 C 里面,i 的地址是不确定的,必须要在 A 的构造函数,且在里面合成一个指针,指向具体类型。

另外,需要注意一点,在合成的 defalt construtor 中,只有 base class subobjects 和 member class objects 会被初始化,所有其它的 nonstatic data member,如整数,整数指针,整数数组等都不会被初始化,因为它们对于编译器来说完全是没有必要的。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值