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

  • 相关阅读:
    2020年. NET Core面试题
    java Context namespace element 'component-scan' and its parser class ComponentScanBeanDefinitionParser are only available on JDK 1.5 and higher 解决方法
    vue 淡入淡出组件
    java http的get、post、post json参数的方法
    vue 父子组件通讯案例
    Vue 生产环境解决跨域问题
    npm run ERR! code ELIFECYCLE
    Android Studio 生成apk 出现 :error_prone_annotations.jar (com.google.errorprone:error) 错误
    记忆解析者芜青【总集】
    LwIP应用开发笔记之十:LwIP带操作系统基本移植
  • 原文地址:https://www.cnblogs.com/k5bg/p/11138006.html
Copyright © 2011-2022 走看看