C++第12章

第12章,类和动态内存的分配

12.1动态内存和类

   12.1.1 复习范例和静态类成员

        1,不能在类声明中初始化静态成员遍历变量,这是因为声明描述了如何分配内存,但是并不分配内存。同时对于静态类成员,可以在类声明之外使用单独的语句来进行初始化。但是如果静态成员是整型或枚举型const,则可以在类声明中初始化。

        2,在构造函数中使用new来分配内存时,必须在相应析构函数中使用delete来释放内存。 如果使用new[](包括中括号)来分配内存,则应使用delete[](包括中括号)来释放内存。

        3,注意如下代码:
      StringBad sailor = sports; 等同于:
           StringBad sailor = StringBad(sports);因此相应的构造函数原型应该如下:
           StringBad (const StringBad &);
           也就是说,当你使用一个对象来初始化另一个对象时,编译器将自动生成上述构造函数(称为复制构造函数,因为它创建对象的一个副本)。

   12.1.2隐式成员函数

        1,C++自动提供了下面这些成员函数:

l  默认构造函数,如果没有定义构造函数。

l  复制构造函数,如果没有定义。

l  复制操作符,如果没有定义。

l  默认析构函数,如果没有定义。

l  地址操作符,如果没有定义

更准确的说,编译器将生成最后四个函数的定义。假如将一个对象赋值给另一个对象,编译器将提供赋值操作符的定义。

         2,复制构造函数

             1,复制构造函数用于将一个对象复制到新创建的对象中。也就是说,它用于初始化过程中,而不是常规的复制过程中。原型如下:
        Class_name (const Class_name &);

             2,何时调用复制构造函数,下面四种声明都将调用:

l  StringBad ditto(motto);

l  StringBad metoo = motto;

l  StringBad also = StringBad(motto);

l  StringBad *pStringBad = new StringBad(motto);

其中中间的两种声明可能会使用复制构站函数直接创建metoo和also,也肯能使用 复制构造函数生成一个临时对象,在将临时对象的内容赋给metoo和also。 最后一个声明使用motto初始化一个匿名对象,并将新对象的地址赋值给pstring指针。
每当程序生成了对象副本时,编译器都将使用复制构造函数。具体说,当函数按值传递对象或函数返回对象时,都将使用复制构造函数。    

3,复制构站函数的功能

l  默认的复制构造函数将一个一个的复制非静态成员(成员复制也成为浅复制),复制的是成员的值。

l  注意默认是按值复制的。也就是说如果两个指针按值赋值得话,指向的是同一个内存位置。所以一定要注意,那个内存位置会不会被释放,然后又被其中一个重新调用。如果要避免,可以使用显式的复制构站函数来解决这个问题。可达到深度复制的目的。

            4,赋值操作符

l  C++允许类对象赋值,这是通过自动为类冲在赋值操作符实现的。这种操作符的原型如下:
 Class_name & Class_name :: operator = (const Class_name &);
它接受并返回一个指向类对象的引用。

l  将已有对象赋值给另一个对象时,将使用重载的赋值操作符。

l  赋值操作符的隐式实现也对成员进行一个一个的复制。如果成员本身就是类对象,则程序将使用为这个类定义的赋值操作符来复制该成员,但对静态数据成员不影响。

l  也是一个浅复制,所以有可能导致不同对象指向同一个地址。为避免,我们应使用提供赋值操作符定义。达到深度复制的目的。

1,  在谈new和delete

在构造函数中通过new地址,在析构函数中通过delete

2,  在以下情况中析构函数将被调用

l  如果对象是动态变量,则当执行完定义该对象的程序块时,将调用该对象的析构函数。

l  如果对象是静态变量(外部,静态,静态外部或来自名称空间),则在程序结束时将调用对象的析构函数。

l  如果对象是用new创建的,则仅当你显式使用delete删除对象是,其析构函数才会被调用。

posted @ 2020-02-27 02:06  风生  阅读(126)  评论(0编辑  收藏  举报