c++ primer plus chapter12 类和动态内存分配

目前有两种构造函数,默认构造函数和普通的传参数的构造函数,如下:

class Test
{
private
    int i;
public:
    Test(){}                  //默认构造函数
    Test(int _i){i = _i;}     //普通构造函数
};

//对应的对象初始化方式如下
Test tmp;
Test tmp(10);

但是有一种对象初始化方式不会调用这两种构造函数中的任何一种,如下:

Test t2 = t1;
Test t2 = Test(t1)

这两个语句是等效的,t1的类型是Test,因此调用的构造函数原型如下

Test(const Test &);

这就是第三种构造函数,复制构造函数,当用一个对象初始化另一个对象的时候,需要使用复制构造函数,若没有显示提供,编译器会自动生成,这就是浅拷贝,若构造函数中涉及内存的时候,就会出问题。程序设计时应该防止编译器自动行为,C++自动提供以下5中成员函数:

1.默认构造函数,若没有定义任何构造函数

2.默认析构函数,若没有定义

3.复制构造函数,若没有定义

4.赋值运算符,若没有定义

5.地址运算符,若没有定义

隐式地址运算符返回一个对象的地址,也就是this指针的值,不会有额外的影响,不需要考虑。c++11还提供了移动构造函数和移动赋值运算符。

复制构造函数的调用场景有如下4种

Test t2(t1);
Test t2 = t1;
Test t2 = Test(t1);
Test *t2 = new Test(t1);

其中中间两种可能直接用复制构造函数,也可能先用复制构造函数创建一个临时对象,然后赋值,这取决于编译器。每当程序产生了对象副本的时候,都调用复制构造函数,比如按值传递到函数参数,或者函数返回对象的时候。编译器生成临时对象的时候,也会调用复制构造函数。这就是函数参数是对象的时候,应该使用引用而不是值,可以减少开销同时避免设计复制构造函数有缺陷导致的问题。

deep copy:不只是赋值指针的值,还申请内存,为了减少开销,可以设置一个内存的引用计数,引用时增加计数,销毁时减少计数,计数为0时释放内存。

赋值运算符的原型如下:

Test & operator=(const Test &);

赋值运算符除了需要解决浅复制的问题之外,还要注意若被赋值的对象之前经过了初始化过程,那么需要先析构将内存释放掉,否则会造成内存泄漏,处理这个要注意引入的一个新问题,就是将一个对象赋值给自己的时候,若先将其内存释放了,后续拷贝就会出问题,因此要增加一个判断。

c++11提供的空指针:nullptr,这样就不用NULL或者(void *)0了

静态类成员函数:声明为static,由于不是对象的一部分,不能通过对象调用,只能使用静态数据成员,通过类名和作用域解析运算符::来调用,如下:

class Test
{
private:
    int i;
    static int j;
public:
    static int lala(){return j;}
};

//调用方法
int j = Test::lala();

关于函数返回对象:当对象作为返回值返回的时候,有几种方式可供选择:

1.返回指向对象的引用

2.返回指向对象的const引用

3.返回const对象

4.返回对象

返回对象会调用复制构造函数,返回引用不会,因此开销更少。若返回对象是函数中的局部变量,那么只能返回对象,否则函数退出时局部变量销毁了。

返回const对象:如下语句,不是编码意图但是可以通过编译,若给重载加法运算符返回const对象,那么就不会通过编译,从而可以发现错误:

Test t1(1);
Test t2(2);
t3 = t1 + t2;
t1 + t2 = t3;        //不是编码意图,通过给重载加法运算符返回const对象,可以编译告警

对于没有公有赋值构造函数的类,比如ostream,只能返回引用。在可以返回引用或者对象的情况下,优先选择引用。

使用定位new给对象分配内存,和直接分配内存的一个区别是,直接用new分配的内存,在delete的时候,会自动调用对象的析构函数,但是使用定位new分配的内存,delete定位new的内存,也不会调用对象的析构函数。

列表初始化:当对象含有非静态const成员的时候,由于const成员只能在初始化时赋值,不能在构造函数的大括号内部赋值,因此使用列表初始化这种特殊方法,如下

class Test
{
private:
    const int i;
public:
    Test() : i(0){}
};

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值