C++笔记——类与对象的构造、复制和析构函数

1、面向对象的程序设计具有四个基本特点

  • 抽象
  • 封装
  • 继承
  • 多态

2、使用类的成员变量和成员函数

  • 对象名.成员名
  • 指针->成员名
  • 引用名.成员名
CRectangle r1,r2;
r1.w = 1;                 //第一种方式
CRectangle * p1 = & r1;
p1->w = 2;                //第二种方式
CRectangle & rr = r2;
rr.w = 3;                 //第三种方式

3、类成员的可访问范围

   (1)在类的定义中,用下列访问范围关键字来说明类成员可被访问的范围:

  • private: 私有成员,只能在成员函数内访问
  • public : 公有成员,可以在任何地方访问
  • protected: 保护成员,继承类可以访问

 (2)定义一个类:

   class className {
       private:
             私有属性和函数
       public:
             公有属性和函数
       protected:
            保护属性和函数
   };

  (3)如过某个成员前面没有上述关键字,则缺省地被认为是私有成员

4、构造函数(constructor)

(1)特点:

  • 名字与类名相同,可以有参数,不能有返回值(void也不行)
  • 作用是对对象进行初始化,如给成员变量赋初值
  • 如果定义类时没写构造函数,则编译器生成一个默认的无参数的构造函数,默认构造函数无参数,不做任何操作
  • 如果定义了构造函数,则编译器不生成默认的无参数的构造函数
  • 对象生成时构造函数自动被调用。对象一旦生成,就再也不能在其上执行构造函数
  • 一个类可以有多个构造函数

 (2)构造函数在数组中的使用

class CSample {
    int x;
public:
    CSample() {
        cout << "Constructor 1 Called" << endl;
    }
    CSample(int n) {
        x = n;
        cout << "Constructor 2 Called" << endl;
    }
};
int main(){                           //输出:
    CSample array1[2];                //Constructor 1 Called
    cout << "step1"<<endl;            //Constructor 1 Called
    CSample array2[2] = {4,5};        //step1
    cout << "step2"<<endl;            //Constructor 2 Called
    CSample array3[2] = {3};          //Constructor 2 Called
    cout << "step3"<<endl;            //step2
    CSample * array4 =                //Constructor 2 Called
    new CSample[2];                   //Constructor 1 Called
    delete []array4;                  //step3
    return 0;                         //Constructor 1 Called
}                                     //Constructor 1 Called

5、复制构造函数(copy constructor)

(1)特点:

  • 只有一个参数,即对同类对象的引用。形如 X::X( X& )或X::X(const X &), 二者选一,后者能以常量对象作为参数
  • 如果没有定义复制构造函数,那么编译器生成默认复制构造函数。默认的复制构造函数完成复制功能。
  • 如果定义的自己的复制构造函数,则默认的复制构造函数不存在。
  • 不允许有形如 X::X( X )的构造函数。
class Complex {
public :
    double real,imag;
    Complex(){ }
    Complex( const Complex & c ) {
        real = c.real;
        imag = c.imag;
        cout << “Copy Constructor called”;
    }
};
Complex c1;
Complex c2(c1);//调用自己定义的复制构造函数,输出 Copy Constructor called

 (2)复制构造函数起作用的三种情况:

  • 当用一个对象去初始化同类的另一个对象时
  • 如果某函数有一个参数是类 A 的对象,那么该函数被调用时,类A的复制构造函数将被调用
  • 如果函数的返回值是类A的对象时,则函数返回时,A的复制构造函数被调用

6、析构函数

(1)特点:

  • 名字与类名相同,在前面加‘~’, 没有参数和返回值,一个类最多只能有一个析构函数。
  • 析构函数对象消亡时即自动被调用。可以定义析构函数来在对象消亡前做善后工作,比如释放分配的空间等。
  • 如果定义类时没写析构函数,则编译器生成缺省析构函数。缺省析构函数什么也不做。
  • 如果定义了析构函数,则编译器不生成缺省析构函数

(2)析构函数和数组:对象数组生命期结束时,对象数组的每个元素的析构函数都会被调用

class Ctest {
public:
    ~Ctest() { cout<< "destructor called" << endl; }
};
int main () {
    Ctest array[2];
    cout << "End Main" << endl;
    return 0;
}
输出:
End Main
destructor called
destructor called

(3)析构函数和运算符 delete:delete  运算导致析构函数调用

(4)析构函数在对象作为函数返回值返回后被调用

class CMyclass {
public:
    ~CMyclass() { cout << "destructor" << endl; }
};
CMyclass obj;
CMyclass fun(CMyclass sobj ) {     // 参数对象消亡也会导致析构函数被调用
    return sobj;                   // 函数调用返回时生成临时对象返回
}
int main(){
    obj = fun(obj);               // 函数调用的返回值(临时对象)被 
    return 0;                     // 用过后,该临时对象析构函数被调用
}

猜你喜欢

转载自blog.csdn.net/wys7541/article/details/81462998