类初始化、构造函数、拷贝构造、列表初始化、对象数组

1、构造函数、拷贝构造函数

       如果不写任何构造函数,编译器会自动添加:默认的构造函数、默认的拷贝构造函数。

       如果自定义了一个构造函数,而没有自定义拷贝构造函数,编译器会自动添加:默认拷贝构造函数。

       如果自定义了一个拷贝构造函数,而没有自定义构造函数,编译器不会添加默认的构造函数。此时因为没有任何普通构造函数,无法定义一个实列对象。因此只定义一个拷贝构造函数是没有意义的,还需要至少自定义一个普通构造函数。

 

       综上,合法的情况如下:

       (1)不自定义任何构造;由编译器添加:默认构造、默认拷贝构造。

       (2)自定义:普通构造;由编译器添加:默认构造。

       (3)自定义:普通构造、默认构造。

 

       有构造/拷贝,不自动构造;

       有拷贝,不自动拷贝;无拷贝,有自动拷贝。

 

       当不定义任何构造函数时,使用默认的构造函数时,可以使用对象的初始化列表来初始化 public 变量。默认构造函数相当于一个按顺序给 所有public变量 赋值的构造函数。

       当不定义拷贝构造函数时,使用默认的拷贝构造函数时,可以进行浅拷贝。默认拷贝构造函数相当于一个按顺序给 所有变量  赋值的构造函数。

 

2、成员:

       有const变量引用变量时,需要自定义构造函数,用列表初始化。这两种变量必须用构造函数在定义的时候初始化,不能调用普通的成员函数初始化。

       有指针变量、引用变量时,并且有拷贝操作(用其它对象赋值、传对象、返回对象)时,需要自定义拷贝构造函数。

 

3、对象数组:

       可以进行列表初始化,甚至在列表里调用构造函数初始化。

       初始化列表实际上是调用构造函数来初始化的。因此,如果没有自定义任何构造函数,初始化列表调用的是默认的构造函数,只能对公有成员进行初始化;如果自定义了构造函数,初始化列表会调用自定义构造函数,对成员进行初始化。

(1)直接传数值

class exam {
    int x;
 public:
    exam(int n) { x=n; }
    int get_x() { return x; }
};

int main()
{ 
   exam ob[4]={ 11, 22, 33, 44 }; 
   for (int i=0;i<4;i++)
       cout << ob[i].get_x( ) << ' ';
   return 0;  
}

(2)调构造函数

class exam {
    int x;
 public:
    exam(int n) { x=n; }
    int get_x() { return x; }
};

int main()
{ 
   exam ob[4]={ exam(11), exam(22), exam(33), exam(44) }; 
   for (int i=0;i<4;i++)
       cout<<ob[i].get_x( )<<' ';
   return 0;  
}

(3)前两个调带一个参数的构造函数,后两个调不带参数的构造函数

class exam {
    int x; 
 public:
    exam() { x=123; }
    exam(int n) { x=n; }
    int get_x() { return x; }
};      

int main()
{ 
    exam ob[4]={55,66};       // 55 66 123 123
    int i;
    for (i=0; i<4; i++) 
        cout << ob[i].get_x() << ' ';
    return 0;  }

(4)传多个参数

class Rectangle{
public:
    Rectangle(int len=10, int wid=10)   
    {
        length=len; 
        width=wid;
    }
    int area()
    {
        return(length*width);
    }
private:
    int length, width;
};

int main()
{ 
    Rectangle rec[3] = {    Rectangle(10,20), 
                            Rectangle(30,40), 
                            Rectangle(50,60)    }; 

    //Rectangle rec[3] = { {10,20}, {30,40}, {50,60} };      //直接传数

    cout<<"The area of rec[0] is "<<rec[0].area()<<endl; 
    cout<<"The area of rec[1] is "<<rec[1].area()<<endl; 
    cout<<"The area of rec[2] is "<<rec[2].area()<<endl; 
    return 0;  
}

4、析构函数

       如果没有在类中定义构造函数,则编译系统自动地生成一个默认的构造函数。这个默认的构造函数,不带任何参数,只能为对象开辟一个存储空间,而不能给对象中的数据成员赋初值。

(1)构造函数 new 动态内存,需要深拷贝,需要在析构中释放 delete 内存

(2)虚函数

(3)如果一个对象被定义在一个函数体内,则当这个函数结束时,该对象的析构函数被自动调用。

(4)若一个对象是使用new运算符动态创建的,在使用delete运算符释放它时,delete会自动调用析构函数。 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值