美文网首页
Boolan(博览网)——C++面向对象高级编程(上)(第二周)

Boolan(博览网)——C++面向对象高级编程(上)(第二周)

作者: Michael_SR | 来源:发表于2017-10-30 00:47 被阅读0次

    1. 简单构造函数的形参名应避免和数据成员名一样

    同名形参屏蔽了成员变量,所以必须用this指针索引,这样程序直接查找内存地址而不是局部的:

    this->width = width; 
    this->height = height; 
    

    否则如下代码会让人混乱:

    width = width;
    height = height; 
    

    2. Copy Constructor(拷贝构造函数)

    如果一个构造函数的第一个参数是自身类类型的引用,且如何额外参数都有默认值,则此构造函数是拷贝构造函数。

    • 拷贝构造函数的第一个参数必须是一个引用类型。
    • 拷贝构造函数要考虑到基类的继承,有继承时则需要在拷贝构造和拷贝赋值中复制base对象成员。
    • 拷贝构造的顺序与你书写的顺序没有关系,无论你写成什么顺序,编译器里已经约定好顺序,即先父类,后原类中对数据定义的顺序。因此,这里的建议就是为了阅读代码方便,书写顺序最好与拷贝构造的顺序一致。
    • 如果要拷贝构造的other是空指针,就没必要在堆中再创建分配,只能是浪费空间。

    3. Copy Assignment Operator(拷贝赋值运算符)

    拷贝赋值运算符接收一个与其所在类相同类型的参数,为了与内置类型的赋值保持一致,赋值运算符通常返回一个指向其左侧运算对象的引用。

    • 拷贝赋值函数一定要自检,如果存在自我赋值,则直接返回,否则当企图存取(访问)对象时,就会产生不确定行为(undefined behavior)。
    if (this == &other)
        return *this;
    
    • 同样,拷贝赋值函数也需要考虑基类的继承应该写成这样的形式:

    Shape::operator = (other);

    这里就是把“operator=”看做一个整体,即Shape的成员函数,然后我们直接传入参数other,这样便调用了shape的默认构造函数,对no进行的赋值操作,这样做的好处是我们完全不必管Shape内部是如何实现的,只要做我们的赋值就可以了。

    最后,拷贝赋值需要考虑other.leftUp指针和自身leftUp指针为空的4种情况。首先我们要判断leftUp是否为空,如果当前类成员leftUp不为空的情况下,继续判断other.leftUp是否为空,如果other.leftUp不为空直接进行赋值,如果other.leftUp为空,需要先delete当前类中的leftUp,然后将其指向nullptr;如果当前类成员leftUp为空的情况下,仍需要继续判断other.leftUp是否为空,如果other.leftUp不为空需要重新分配内存,并同时在堆中初始化,如果other.leftUp为空,不需要任何操作。

        if(leftUp != nullptr)
        {
            if(other.leftUp != nullptr)
            {
                *leftUp = *(other.leftUp);
            }
            else
            {
                delete leftUp;
                leftUp = nullptr;
            }
        }
        else
        {
            if(other.leftUp != nullptr)
            {
                leftUp = new Point(*(other.leftUp));
            }
        }
    

    4. Destructor(析构函数)

    析构函数执行与构造函数相反的操作:构造函数初始化对象的非static数据成员,还可能做一些其他工作;析构函数释放对象使用的资源,并销毁对象的非static数据成员。
    析构函数是类的一个成员函数,名字由波浪号接类名构成。它没有返回值,也不接受参数,因此它不能被重载。对一个给定类,只会有唯一一个析构函数

    inline
     Rectangle::~Rectangle()
     {
         delete leftup;
         leftup = nullptr;
     }
    

    ​delete只是对指针的指向空间的释放,并不会改变指针的值,即指针不为空。指针的本身内容,即指向空间的地址,是没有发生变化的。同时,C++是可以delete空指针的,C++不能直接delete的是野指针,是会出问题的,所以一般指针被delete之后,最好立即赋值为空,以免被再次delete而出现问题。当指针为空指针时,没有空间可释放,也就不去释放了。有些代码表面看起来没用,但是要养成好习惯,否则bug出现的时候都不知道错误在哪里。

    5. class with pointer members 必须有copy ctor 和 copy op =,使用default copy ctor 或 default copy op = 就会存在内存泄漏(memory leak)

    相关文章

      网友评论

          本文标题:Boolan(博览网)——C++面向对象高级编程(上)(第二周)

          本文链接:https://www.haomeiwen.com/subject/lfbupxtx.html