zoukankan      html  css  js  c++  java
  • C++03:论类的构造函数和析构函数

    一、构造函数(constructors)

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

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

    1.无参构造函数

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

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

    2.带参构造函数

    3.初始化列表构造函数

    Test::Test(int a):A(a)
    {
     
    }
     
    //等同于下面
    Test::Test(int a)
    {
        this->A=a;
    }
    

    4.拷贝构造函数

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

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

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

    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)

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

    三、函数默认初始化

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

    四.调用顺序

    (1)析构函数不加virtual

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

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

    //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;
        }
    }
    
    //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,那么动态绑定子类的析构函数也会一起进行调用

    //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;
        }
    }
    
    //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

  • 相关阅读:
    mongdb aggregate聚合操作
    mongdb group聚合操作
    mongodb复制集
    springboot2.0数据制作为excel表格
    mongodb索引
    校招真题练习025 瞌睡(网易)
    校招真题练习024 牛牛的闹钟(网易)
    校招真题练习023 俄罗斯方块(网易)
    校招真题练习022 数对(网易)
    校招真题练习021 迷路的牛牛(网易)
  • 原文地址:https://www.cnblogs.com/k5bg/p/11138006.html
Copyright © 2011-2022 走看看