C++构造与析构(14) - 编译器何时创建默认构造函数和拷贝构造函数

C++中,如果用户没有定义构造函数,则编译器会创建一个默认构造函数,且函数体是空的。它不会自动对数据成员进行初始赋值(在Java中,默认构造函数是会赋初始值的)。

同样地,如果用户没有定义拷贝构造函数,则编译器也会创建一个默认的拷贝构造函数。与默认构造函数不同,默认拷贝构造函数的函数体不为空,它会将传递进来的对象的所有数据成员拷贝给正在创建的对象。

场景1

用户只定义了拷贝构造,编译器是否还会创建默认构造函数?
如果用户创建了任意的构造函数,即使它是一个拷贝构造函数,编译器也不会再创建一个默认的构造函数了。
例如,下面的程序会编译失败。

#include <iostream>
using namespace std;

class Point
{
   int x, y;
public:
   //只定义了拷贝构造函数
   Point(const Point &p) { x = p.x; y = p.y; }
};
 
int main()
{
    Point p1;  // 编译错误
    Point p2 = p1;
    return 0;
}

输出:
error: no matching function for call to 'Point::Point()

场景2

相反,如果用户只定义了构造函数,编译器是否会创建拷贝构造函数?
反过来的情况与上面的情况有所不同。即使用户没有定义拷贝构造,编译器会自动创建一个。即使用户定义了其它的构造函数(非拷贝构造),编译器也会创建一个拷贝构造。
例如,下面的程序可以编译通过。

#include <iostream>
using namespace std;
 
class Point
{
    int x, y;
public:
   Point(int i, int j) { x = 10; y = 20; }
   int getX() { return x; }
   int getY() { return y; }
};
 
int main()
{
    Point p1(10, 20);
    Point p2 = p1; // 编译正常。编译器会自动创建拷贝构造。
    cout << "x = " << p2.getX() << " y = " << p2.getY();
    return 0;
}

输出:
x = 10 y = 20
所以,仅当类中包含有指针成员,或动态分配的资源时,用户才需要自定义拷贝构造函数。否则就可以使用编译器生成的拷贝构造函数。

总结

参考C++ Object Model (by Lipman)
只有在下面的4种情况下,编译器会自动生成默认构造函数:
1. 类的成员对象有默认构造函数
2. 基类有默认构造函数
3. 包含有虚函数的类
4. 有Virtual Base Class(虚基类)的类

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值