C++03:论类的构造函数和析构函数

一、构造函数(constructors)

构造函数命名与类名完全相同,它没有返回值,也不能用void修饰

构造函数不能被直接调用,必须通过创建对象时才会自动调用

 

1.无参构造函数

默认构造函数必须是无参构造函数

1
2
3
4
5
6
7
class  Test{
public:
    Test(){}  //默认构造函数
}
  
Test t;      //默认调用无参构造函数
Test t();    //错误,不能加括号,这表示函数

 

2.带参构造函数

3.初始化列表构造函数

1
2
3
4
5
6
7
8
9
10
Test::Test(int a):A(a)
{
  
}
  
//等同于下面
Test::Test(int a)
{
    this->A=a;
}

 

4.拷贝构造函数

(1)浅拷贝

 

1
2
3
4
5
6
7
8
9
10
11
12
//如果没写拷贝构造函数,系统会默认一个拷贝构造函数,把各个成员属性复制过去
class Test{
public:
    //拷贝构造函数的特点是参数是同类对象
    Test(const Test& t){
        this->A=t.A;
    }
  
};
  
//调用
Test T(t);

 

 

 

(2)深拷贝

注意:当只有类成员带有指针的时候,才有浅拷贝和深拷贝之分。如果只有变量、结构体的话,它们只能拷贝了值过去。

浅拷贝只是对指针的拷贝,拷贝后两个指针指向同一个内存空间,深拷贝不但对指针进行拷贝,而且对指针指向的内容进行拷贝,经深拷贝后的指针是指向两个不同地址的指针

1
2
3
4
5
6
7
8
9
Test(const Test& t){
    A=new int();  //另外分配内存给另一个对象,如果同时指向相同的指针地址,会导致析构两次
    *A=*(t.A);
}
  
Test(const Test& t){
    A=new char(20);
    memcpy(A,t.A,strlen(t.A));
}

 

二、析构函数(destructors)

析构函数无参数,无返回值,名字与类名相同,前面加个~

 

三、函数默认初始化

1
2
3
4
//这个主要是用在有时候调用这个函数需要这个参数,有时候不需要这个参数
void  A(int a,int b=0){
  
}

 

四.调用顺序

(1)析构函数不加virtual

在构造一个子类对象的时候,先调用基类的构造函数,此时子类成员还没有初始化,虚函数不起作用.再调用子类的构造函数

在析构一个子类对象的时候,先调用子类的析构函数,再调用基类的析构函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//TestMain.h
  
class A{
     
public:
    A(){
        cout<<"A+"<<endl;
    }
  
  
    ~A(){
        cout<<"A-"<<endl;
    }
}
  
class B:public A{
  
public:
    B(){
        cout<<"B+"<<endl;
    }
    
    ~B(){
       cout<<"B-"<<endl;
    }
}

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//TestMain.cpp
  
int main(){
  
    A* a=new A();  //输出A+ A-
    delete a;
  
    B* b=new B();  //输出A+ B+ B- A-
    delete b;
  
    A* a=new B();  //输出A+ B+ A-
    delete a; 
  
    system("pause");
    return 0;
}

 

(2)析构函数加virtual

如果父类析构函数加上virtual,那么动态绑定子类的析构函数也会一起进行调用

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//TestMain.h
  
class A{
     
public:
    A(){
        cout<<"A+"<<endl;
    }
  
  
    ~A(){
        cout<<"A-"<<endl;
    }
}
  
class B:public A{
  
public:
    B(){
        cout<<"B+"<<endl;
    }
    
    ~B(){
       cout<<"B-"<<endl;
    }
}

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//TestMain.cpp
  
int main(){
  
    A* a=new A();  //输出A+ A-
    delete a;
  
    B* b=new B();  //输出A+ B+ B- A-
    delete b;
  
    A* a=new B();  //输出A+ B+ B- A-
    delete a; 
  
    system("pause");
    return 0;
}

 

(3)构造函数不能加virtual

 

posted @   言午丶  阅读(319)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示