C++析构函数

功能:销毁对象前执行清除工作

格式:

[类名::]~类名()

{

   ....

}

class Student
{public:
    Student(...);
    ~Student();//~符号
    void display()const;
private:
    int    m_iNum;
    string m_strName;
    char   m_cSex;
};
Student::~Student()
{ cout<<"Destructor "<<endl;}
… …

注意:

函数名与类名相同,且函数名前加~

没有参数、不能被重载

不指定返回值

常定义为public

对象生命期结束时自动调用

思考:

通常不需人为定义析构函数,什么时候必须定义析构函数?

一般,当类中含有指针成员,并且在构造函数中用指针指向了一块堆中的内存,则必须定义析构函数释放该指针申请的动态空间

#include<iostream>
using namespace std;

class String
{
public:
    String();
    void display() const;
private:
    char *m_pstr;
};

String::String()
{
    m_pstr = new char[1000];
    strcpy(m_pstr, "hello");
}
void String::display() const
{
    cout<<m_pstr<<endl;
}
/*
String::~String()
{
    //系统生成的
}
*/
int main()
{
    String str;
    str.display();
    system("pause");
    return 0;
} 

看下面的代码,使用自己定义的析构函数--示例代码1:

#include<iostream>
using namespace std;

class String
{
public:
    String();
    ~String();
    void display() const;
private:
    char *m_pstr;
};

String::String()
{
    m_pstr = new char[1000];
    strcpy(m_pstr, "hello");
}
String::~String()
{
    delete []m_pstr;
}
void String::display() const
{
    cout<<m_pstr<<endl;
}

int main()
{
    String str;
    str.display();
    system("pause");
    return 0;
} 

示例代码2:

#include<iostream>
using namespace std;

class String
{
public:
    String(char *ap = "china");
    ~String();
    void display() const;
private:
    char *m_pstr;
};

String::String(char *ap)
{
    m_pstr = new char[strlen(ap)+1];
    strcpy(m_pstr, ap);
}
String::~String()
{
    delete []m_pstr;
}
void String::display() const
{
    cout<<m_pstr<<endl;
}

int main()
{
    String str1("USA");
    str1.display();
    String str2;
    str2.display();
    system("pause");
    return 0;
} 

如果要定义析构函数,通常也需要定义拷贝构造函数和赋值运算符的重载函数。

时间: 2024-12-01 17:13:22

C++析构函数的相关文章

理解finalize()-析构函数替代者

函数 理解finalize()-析构函数替代者   在许多方面,Java 类似于 C++.Java 的语法非常类似于 C++,Java 有类.方法和数据成员:Java 的类有构造函数: Java 有异常处理.       但是,如果你使用过 C++ 会发现 Java 也丢掉一些可能是你熟悉的特性.这些特性之一就是析构函数.取代使用析构函数,Java 支持finalize() 方法.       在本文中,我们将描述 finalize() 与 C++ 析构函数的区别.另外,我们将创建一个简单的 A

ASP 类成员变量、成员函数、构造析构函数

class CFoo    dim publicParam '用 dim 申明公有成员变量    private privateParam '用 private 申明私有成员变量    'publicParam = "公有" '不能在 class 标记以内.类函数以外为成员变量赋值    'const MAX_LEN = 5 '不能在 class 标记以内.类函数以外使用 const        '该函数为构造函数,在使用 set new 创建对象时,自动执行    private

C#中构造函数和析构函数的用法

函数 摘 要:构造函数与析构函数是一个类中看似较为简单的两类函数,但在实际运用过程中总会出现一些意想不到的运行错误.本文将较系统的介绍构造函数与析构函数的原理及在C#中的运用,以及在使用过程中需要注意的若干事项. 关键字:构造函数:析构函数:垃圾回收器:非托管资源:托管资源一.构造函数与析构函数的原理 作为比C更先进的语言,C#提供了更好的机制来增强程序的安全性.C#编译器具有严格的类型安全检查功能,它几乎能找出程序中所有的语法问题,这的确帮了程序员的大忙.但是程序通过了编译检查并不表示错误已经

高质量C++/C编程指南-第9章-类的构造函数、析构函数与赋值函数(4)

类String的赋值函数比构造函数复杂得多,分四步实现: (1)第一步,检查自赋值.你可能会认为多此一举,难道有人会愚蠢到写出 a = a 这样的自赋值语句!的确不会.但是间接的自赋值仍有可能出现,例如 // 内容自赋值 b = a; - c = b; - a = c; // 地址自赋值 b = &a; - a = *b; 也许有人会说:"即使出现自赋值,我也可以不理睬,大不了化点时间让对象复制自己而已,反正不会出错!" 他真的说错了.看看第二步的delete,自杀后还能复制自

理解finalize()-析构函数的替代者

在许多方面,Java 类似于 C++.Java 的语法非常类似于 C++,Java 有类.方法和数据成员:Java 的类有构造函数: Java 有异常处理. 但是,如果你使用过 C++ 会发现 Java 也丢掉一些可能是你熟悉的特性.这些特性之一就是析构函数.取代使用析构函数,Java 支持finalize() 方法. 在本文中,我们将描述 finalize() 与 C++ 析构函数的区别.另外,我们将创建一个简单的 Applet 来演示 finalize() 是如何工作的. 最终的界限 与 J

C#构造函数和析构函数的用法

构造函数与析构函数是一个类中看似较为简单的两类函数,但在实际运用过程中总会出现一些意想不到的运行错误.本文将较系统的介绍构造函数与析构函数的原理及在C#中的运用,以及在使用过程中需要注意的若干事项. 一.构造函数与析构函数的原理 作为比C更先进的语言,C#提供了更好的机制来增强程序的安全性.C#编译器具有严格的类型安全检查功能,它几乎能找出程序中所有的语法问题,这的确帮了程序员的大忙.但是程序通过了编译检查并不表示错误已经不存在了,在"错误"的大家庭里,"语法错误"

析构函数

在类的实例超出范围时,我们希望确保它所占的存储能被收回.C#中提供了析构函数,用于专门释放被占用的系统资源. 析构函数的名字与类名相同,只是在前面加上了一个符号"~".析构函数不接受任何参数,也不返回任何值.如果你试图声明其它任何一个以符号"~"开头而不与类名相同的方法,和试图让析构函数返回一个值一样,编译器都会产生一个错误. 析构函数不能是继承而来的,也不能显式地调用.当某个类的实例被认为不再有效,符合析构的条件,析构函数就可能在某个时刻被执行.C++程序员常常需

《Effective C++》读书笔记08:别让异常逃离析构函数

这节和异常有关,这一块是我不太熟悉的,只能先把自己理解的记录下来. 1 class Widget 2 { 3 public: 4 5 ~Widget() {} //假设这里会吐出一个异常 6 }; 7 8 void doSomething() 9 { 10 std::vector<Widget> v; 11 12 }//v在这里自动销毁 上面的代码中,假设v含有10个Widget,如果在前面几个的析构函数中弹出异常,则程 序会过早结束或者出现不明确行为. 确实不鼓励在析构函数中抛出异常,可是如

《Effective C++》读书笔记07:为多态基类声明virtual析构函数

这个问题在实践中偶尔会碰到,设计一个TimeKeeper基类和一些派生类来记录时间: 1 class TimeKeeper 2 { 3 public: 4 TimeKeeper (); 5 ~TimeKeeper(); 6 7 }; 8 9 class AtomicClock: public TimeKeeper {}; //原子钟 10 class WaterClock: public TimeKeeper {}; //水钟 在使用时,我们可能会使用factory工厂方法: 1 TimeKee

C++中禁止异常信息传递到析构函数外

在有两种情况下会调用析构函数.第一种是在正常情况下删除一个对象,例如对象超出了作用域或被显式地delete.第二种是异常传递的堆栈辗转开解(stack-unwinding)过程中,由异常处理系统删除一个对象. 在上述两种情况下,调用析构函数时异常可能处于激活状态也可能没有处于激活状态.遗憾的是没有办法在析构函数内部区分出这两种情况.因此在写析构函数时你必须保守地假设有异常被激活,因为如果在一个异常被激活的同时,析构函数也抛出异常,并导致程序控制权转移到析构函数外,C++将调用terminate函