精华内容
下载资源
问答
  • 浅析:只能有一个析构函数

    千次阅读 2015-04-01 12:42:11
    的构造函数与析构函数都是与同名(析构函数需要加上'~'),没有返回值的;...但是由于析构函数是没有参数的,那么从而无法通过参数的不同来达到重载多个析构函数的目的,从而析构函数只能有一个。 析构函数是由系

    类的构造函数与析构函数都是与类同名(析构函数需要加上'~'),没有返回值的;而构造函数是可以有参数的,但是析构函数是不能有参数的。

    我们知道类可以有多个构造函数,这些构造函数是重载函数的关系,也就是说函数名都是相同的,区别它们主要靠参数的不同(参数个数和参数类型)。

    但是由于析构函数是没有参数的,那么从而无法通过参数的不同来达到重载多个析构函数的目的,从而析构函数只能有一个。

    析构函数是由系统负责调用的,也可以手工显示调用,但是显示调用析构函数是不会析构该对象的,也就是说显示调用析构函数和没有显示调用析构函数是一样的,

    #include<iostream>
    using namespace std;
    class A
    {
    public:
       A(){};
       void fun() {cout<<"The object exists!";};
       ~A(){};

      int bbb;
    };
    int main()
    {
       A *a=new A();

      a->bbb=345;
       a->~A();//显示调用析构函数后,对象a还存在吗?
       a->fun();
       //编译运行后a->fun()能够输出,对象a仍存在
       return 0;

    再来看看汇编代码

    在VC的DEBUG模式下,通过查看反汇编代码,可以看到,直接调用析构函数的语句没有任何汇编代码对应它,就和没有这一语句一模一样.由此看来,析构函数是自动调用的,如果显示调用是不会析构对象的。
    ……
    14:       a->bbb = 345;
    0040105B   mov         ecx,dword ptr [ebp-4]
    0040105E   mov         dword ptr [ecx],159h
    15:       a->~A();
    16:       a->fun();
    00401064   mov         ecx,dword ptr [ebp-4]
    00401067   call        @ILT+15(A::fun) (00401014)
    ……

    由以上可知,一个类只能有一个析构函数,析构函数没有返回值没有参数,只能由系统调用时才析构对象。

    展开全文
  • C++中有一个很重要的法则:使用构造函数创建对象的顺序与使用析构函数释放对象的顺序相反。对于一些C++的初学者来说,这是一条有点费解的法则,那么该怎么理解和清晰的表现出来呢?下面我们通过程序来体现一下: #...

           在C++中有一个很重要的法则:使用构造函数创建对象的顺序与使用析构函数释放对象的顺序相反。对于一些C++的初学者来说,这是一条有点费解的法则,那么该怎么理解和清晰的表现出来呢?下面我们通过程序来体现一下:

    #include<iostream>
    using namespace std;
    
    //创建一个汽车类
    class Car
    {
    public:
            //构造函数
    	Car(short, int);
            //析构函数
    	~Car();
    	void move();
    private:
    	short speed;
    	int num;
    };
    
    Car::Car(short s, int n)
    {
    	speed = s;
    	num = n;
    	cout << "创建第" << num << "辆车,速度是" << speed << " 米/秒" << endl;
    }
    
    Car::~Car()
    {
    	cout << "销毁掉第 " << num << "辆车" << endl;
    }
    
    void Car::move()
    {
    	cout << "第 " << num << "辆车速度是" << speed << endl;
    }
    
    //主函数
    void main()
    {
            //先创建第car1对象,再创建car2对象
    	Car car1(10, 1), car2(20, 2);
    	car1.move();
    	car2.move();
    }

           编译执行的结果如下(编译环境为Visual Studio 2013):


           分析输出结果,我们可以看到,在主函数中是首先创建了car1类,后创建了car2类,所以在执行构造函数的顺序上,是先执行car1对象的构造函数,后执行car2对象的构造函数。而在主函数执行结束,要调用析构函数的时候,根据开始说的法则,则会先执行car2类的析构函数,后执行car1类的析构函数。这就是“使用构造函数创建对象的顺序与使用析构函数释放对象的顺序相反”这条法则的一个很好的体现

           那么我们可以举一反三,如果想先执行car1类的析构函数,后执行car2类的析构函数,那么上述程序该如何修改呢?很简单,依据上述法则,我们只需要修改为先创建car2类,后创建car1类,就可以了。修改后的程序如下:

    #include<iostream>
    using namespace std;
    
    class Car
    {
    public:
    	Car(short, int);
    	~Car();
    	void move();
    private:
    	short speed;
    	int num;
    };
    
    Car::Car(short s, int n)
    {
    	speed = s;
    	num = n;
    	cout << "创建第" << num << "辆车,速度是" << speed << " 米/秒" << endl;
    }
    
    Car::~Car()
    {
    	cout << "销毁掉第 " << num << "辆车" << endl;
    }
    
    void Car::move()
    {
    	cout << "第 " << num << "辆车速度是" << speed << endl;
    }
    
    void main()
    {
            //这次先创建car2类,后创建car1类
    	Car car2(20, 2), car1(10, 1);
    	car1.move();
    	car2.move();
    }
           编译执行的结果如下:

           这次我们看到,由于是先创建了car2类,后创建了car1类,所以先执行了car2类的构造函数,后执行car1类的构造函数;而在最后,会先执行car1类的析构函数,后执行car2类的西沟函数。

           当然。我们还可以再往深了想一想,上面这两个例子都是基于同一个类来创建两个对象的,那么如果是两个不同的类创建的对象呢?是否依然符合这条法则呢?我们再修改程序来验证一下:

    #include<iostream>
    using namespace std;
    
    //创建一个汽车类
    class Car
    {
    public:
    	Car(short, int);
    	~Car();
    	void move();
    private:
    	short speed;
    	int num;
    };
    
    //创建一个司机类
    class Driver
    {
    public:
    	Driver(short);
    	~Driver();
    	void drive();
    private:
    	short years;
    };
    
    Car::Car(short s, int n)
    {
    	speed = s;
    	num = n;
    	cout << "创建第" << num << "辆车,速度是" << speed << " 米/秒" << endl;
    }
    
    Car::~Car()
    {
    	cout << "销毁掉第 " << num << "辆车" << endl;
    }
    
    void Car::move()
    {
    	cout << "第 " << num << "辆车速度是" << speed << endl;
    }
    
    Driver::Driver(short y)
    {
    	cout << "我是一个" << y << "岁的司机" << endl;
    }
    
    Driver::~Driver()
    {
    	cout << "我要停车了" << endl;
    }
    
    void Driver::drive()
    {
    	cout << "我要开车了" << endl;
    }
    
    //主函数
    void main()
    {
            //先创建汽车类
    	Car car1(10, 1);
            //后创建司机类
    	Driver driver1(30);
    	driver1.drive();
    	car1.move();
    }
           编译执行的结果如下:

           通过输出结果,我们可以看到,先执行了Car1类的构造函数,后执行了Driver1类的构造函数,而在最后,则是先执行了Driver1类的析构函数,后执行了Car1类的析构函数,也就是说,不同的类依然是符合上述法则的

           上述例子较为简单,而在实际应用中,主函数中可能远比上述程序复杂的多,可能会执行更多的类操作,这样就需要我们去时刻注意一下这条法则,避免出现一些看起来很“莫名其妙”的错误。



    展开全文
  • C++析构函数析构函数介绍:示例:参考链接     析构函数是类的另一个特殊成员函数...换言之,一个类可以有多个构造函数,但是只能有一个析构函数。 析构函数介绍: 1.析构函数(destructor) 与构造函数相反,当对...


        析构函数是类的另一个特殊成员函数,它的作用与构造函数相反,C++规定析构函数的名字是类的前面加上一个波浪号 (~)。
        析构函数不返回任何值,没有返回类型,也没有函数参数。由于没有函数参数,因此它不能被重载。换言之,一个类可以有多个构造函数,但是只能有一个析构函数。

    析构函数介绍:

        1.析构函数(destructor) 与构造函数相反,当对象脱离其作用域时(例如对象所在的函数已调用完毕),系统自动执行析构函数。析构函数往往用来做“清理善后” 的工作(例如在建立对象时用new开辟了一片内存空间,应在退出前在析构函数中用delete释放)。
        2.以C++语言为例:析构函数名也应与类名相同,只是在函数名前面加一个位取反符,例如stud( ),以区别于构造函数。它不能带任何参数,也没有返回值(包括void类型)。只能有一个析构函数,不能重载。如果用户没有编写析构函数,编译系统会自动生成一个缺省的析构函数(即使自定义了析构函数,编译器也总是会为我们合成一个析构函数,并且如果自定义了析构函数,编译器在执行时会先调用自定义的析构函数再调用合成的析构函数),它也不进行任何操作。所以许多简单的类中没有用显示的析构函数。

    示例:

    #include<iostream>
    using namespace std;
    class T
    {
        public:
         ~T(){cout<<"析构函数被调用。";} 
     };
    int main()
    {
         T *t=new T();//建立一个T类的指针对象t
         delete t;
         cin.get();
    };
    

    运行结果:
    在这里插入图片描述

    参考链接

    https://blog.csdn.net/qq_15267341/article/details/78585570
    https://www.cnblogs.com/liuzhenbo/p/11214276.html

    展开全文
  • 尽管纯虚析构函数在标准C++中是合法的,但在使用时有一个额外的限制:必须 为纯虚析构函数提供一个函数体 纯虚析构函数和非纯虚析构函数之间唯一的不同之处在于纯虚析构函数使得 基类是抽象,所以不能创建一个基类...

    尽管纯虚析构函数在标准C++中是合法的,但在使用时有一个额外的限制:必须
    为纯虚析构函数提供一个函数体

    纯虚析构函数和非纯虚析构函数之间唯一的不同之处在于纯虚析构函数使得
    基类是抽象类,所以不能创建一个基类的对象

    //: C15:UnAbstract.cpp
    // From Thinking in C++, 2nd Edition
    // Available at http://www.BruceEckel.com
    // (c) Bruce Eckel 2000
    // Copyright notice in Copyright.txt
    // Pure virtual destructors 
    // seem to behave strangely
    
    class AbstractBase {
    public:
      virtual ~AbstractBase() = 0;
    };
    
    AbstractBase::~AbstractBase() {}
    
    class Derived : public AbstractBase {};
    // No overriding of destructor necessary?
    
    int main() { Derived d; } ///:~

    一般来说,如果在派生类中基类的纯虚函数没有重新定义,则派生类将会
    成为抽象类

    当我们的类仅含有一个纯虚函数时,就会发现这个唯一的差别:析构函数

    运行下面的程序,可以看到在派生类版本之后,随着任何其他的析构函数,
    调用了纯虚函数体

    //: C15:PureVirtualDestructors.cpp
    // From Thinking in C++, 2nd Edition
    // Available at http://www.BruceEckel.com
    // (c) Bruce Eckel 2000
    // Copyright notice in Copyright.txt
    // Pure virtual destructors
    // require a function body
    #include <iostream>
    using namespace std;
    
    class Pet {
    public:
      virtual ~Pet() = 0;
    };
    
    Pet::~Pet() {
      cout << "~Pet()" << endl;
    }
    
    class Dog : public Pet {
    public:
      ~Dog() {
        cout << "~Dog()" << endl;
      }
    };
    
    int main() {
      Pet* p = new Dog; // Upcast
      delete p; // Virtual destructor call
      getchar();
    } ///:~

    作为一个准则,任何时候我们的类做都要有一个虚函数,我们应当立即增加
    一个虚析构函数

    输出
    ~Dog()
    ~Pet()

    展开全文
  • 每个类只有一个析构函数和一个赋值函数,但可以有多个构造函数(包含一个拷贝 构造函数,其它的称为普通构造函数)。对于任意一个类 A,如果不想编写上述函数, C++编译器将自动为 A 产生四个缺省的函数。 ...
  • 每个类只有一个析构函数和一个赋值函数,但可以有多个构造函数(包含一个拷贝构造函数,其它的称为普通构造函数)。对于任意一个类A,如果不编写上述函数,C++编译器将自动为A 产生四个缺省的函数,例如:  A(void...
  •  每个类只有一个析构函数和一个赋值函数,但可以有多个构造函数(包含一个拷贝构造函数,其它的称为普通构造函数)。对于任意一个类A,如果不想编写上述函数,C++编译器将自动为A产生四个缺省的函数,如  A...
  • C++ 析构函数

    2019-03-29 13:10:00
    一个类最多只能有一个析构函数。析构函数不返回任何值,没有函数类型,也没有函数参数,因此它不能被重载。 构造函数可能有多个,但析构函数只能有一个,就像人来到人世间,可能出生的环境家庭不同(重载构造函数)...
  • 1.每个类只有一个析构函数和一个赋值函数,但是可以有多个构造函数(一个拷贝构造函数,其他为普通构造函数) 2.对于任意一个类A,如果不想编写上类函数,c++编译器会自动生成四个缺省的函数 A(void); A(const A &a);...
  • 默认构造函数指不带参数或者所有参数都有缺省值的构造函数!...每个类只有一个析构函数和一个赋值函数,但可以有多个构造函数(包含一个拷贝构造函数,其它的称为普通构造函数)。对于任意一个类A,如果不编写上述
  • 1.每个类只有一个析构函数和一个赋值函数,但可以有多个构造函数(包括一个拷贝构造函数,其它的称为普通构造函数)。对于任意一个类A,如果不想编写上述函数,C++编译器将自动为A产生四个缺省的函数,如: A(void);...
  • 析构函数(只能有一个)3.malloc、free、new、delete 区别4. 拷贝构造函数和调用场景 知识点: 面试题:finalize , finally, final 之间的区别 finalize : java中垃圾回收回收该对象的时候会调用的方法 (c 中的析构...
  • 在继承关系中,虚函数、虚析构函数、虚基类中使用的关键字virtual都是在告诉编译器,此处要...虚基类:当派生类有多重继承和继承时,在继承链上有两个子类继承自同一基类时,此两个子类作为基类再次派生出一个类...
  • 每个类只有一个析构函数和一个赋值函数,但可以有多个构造函数(包含一个拷贝构造函数,其它的称为普通构造函数)。对于任意一个类A,如果不想编写上述函数,C++编译器将自动为A产生四个缺省的函数
  • 在C++的中,都会有一个多个构造函数、一个析构函数一个赋值运算操作符。即使我们自己定义的中,没有显示定义它们,编译器也会声明一个默认构造函数、一个析构函数一个赋值运算操作符。例如: 1 //声明...
  • 所谓初始化,就是把一个刚创建的数据设置成我想要的值,而不是一个不能掌控的随机数。 如果初始化用的是一般的赋值,当属性很且而大部分属性都是默认的情况下,这种方法会麻烦。 c++为提供了初始化函数,这个...
  • C++析构函数

    2021-02-12 09:55:21
    析构函数 1.析构函数定义 2.析构函数作用 执行用户希望在最后一次使用对象之后所执行的任何操作,通常用来...一个类可以有多个构造函数,但只能有一个析构函数 用户没有定义析构函数,系统会自动生成一个析构函数 ...
  • C++构造函数和析构函数 默认构造函数指不带参数或者所有参数都有缺省值的构造...每个类只有一个析构函数和一个赋值函数,但可以有多个构造函数(包含一个拷贝构造函数,其它的称为普通构造函数)。对于任意一个类A...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 758
精华内容 303
关键字:

一个类有多个析构函数