c++合成默认构造函数与new关键字带不带括号的分析

本文详细探讨了C++中声明类对象时是否调用默认构造函数,以及new运算符带括号与不带括号的区别。重点讲解了编译器在哪些情况下会合成默认构造函数,并分析了new创建对象时,对于内置类型和自定义类型的不同行为。总结了四种编译器合成默认构造函数的场景,并澄清了关于默认构造函数的一些误解。
摘要由CSDN通过智能技术生成

声明或定义一个类/对象的时候,会因为类本身的成员结构而会引起不同的构造函数的调用,之前的学习中或多或少有些总结。《c++primer(第五版)》《深度探索c++对象模型》《More Effective C++》三本书中都有总结,自己也简单的理解了下



全篇总结:

一,声明一个类对象时,不一定是调用了默认的构造函数;只有在没有任何构造函数且AA xx{}声明的时候,编译器才会对内置类型进行“零值化”;其他情况按照四种情况进行分析

二,编译器有四种情况会合成默认的构造函数
1. 包含了一个类的对象,这个对象有一个构造函数(包括编译器合成的默认构造函数)
2. 继承自一些基类,其中某些基类有一个构造函数(包括编译器合成的默认构造函数)
3. 有一个虚函数,或者继承到了虚函数
4. 有虚基类
两种错误的观点:
a) 任何类如果没有定义构造函数,则编译器会帮我们合成一个默认构造函数。
b) 合成默认构造函数会对类中的每一个数据成员进行初始化。

三,new对象的时候带不带括号
对于自定义类类型:
如果该类没有定义构造函数(由编译器合成默认构造函数)也没有虚函数,那么class c = new class;将不调用合成的默认构造函数,而class c = new class();则会调用默认构造函数。
如果该类没有定义构造函数(由编译器合成默认构造函数)但有虚函数,那么class c = new class;将不调用合成的默认构造函数;class c = new class()会调用默认构造函数。
如果该类定义了默认构造函数,那么class c = new class;和class c = new class();一样,都会调用默认构造函数。。

对于内置类型:
int *a = new int;不会将申请到的int空间初始化,而int *a = new int();则会将申请到的int空间初始化为0。



1,声明一个类的时候,不一定是调用了默认构造函数

如下:

class HasExplicitCon{
public:
    HasExplicitCon(){
cout<<"显式的定义一个默认构造函数"<<endl;
    }
    HasExplicitCon(int a){
cout<<"显式的定义一个有参数默认构造函数"<<endl;
    }

    int a;
};
int main(int argc, char **argv) {
    HasExplicitCon hasObject1;
    HasExplicitCon hasObject2(2);
    HasExplicitCon hasObject3();

    cout<<hasObject1.a<<endl;
    cout<<hasObject2.a<<endl;
    //cout<<hasObject3.a<<endl;  编译不通过
    return 0;
}

结果为:

显式的定义一个默认构造函数
显式的定义一个有参数默认构造函数
4213675
7602016

是的,没看错,结果只输出了两行,因为hasObject3后面跟的是小括号,会引起c++歧义,误以为是定义的一个函数,这点在之前的文章中说过了http://blog.csdn.net/hll174/article/details/78309212。用中括号的话则不会,中括号实际是initializer_list,http://zh.cppreference.com/w/cpp/language/list_initialization
std::initializer_list 对象在这些时候自动构造:
- 花括号初始化器列表用于列表初始化,包括函数调用列表初始化和赋值表达式
- 花括号初始

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值