===============================================
未完待续,转载时请表明出处:http://www.cofftech.com/thread-1395-1-1.html
欢迎大家跟帖讨论哈~~~~~
===============================================
用户所定义的析构函数主要用于释放在建立对象时构造函数从堆区中分配的空间。
和构造函数相同,只当用户在类中定义了析构函数后,程序删除对象时系统才调用析构函数。
析构函数是类的特殊成员函数,它的名字也与类名相同,只是在前面加一个符号“~”。析构函数没有任何参数,也不返回任何值。
[例1]析构函数的用途
#include <string.h>
#include <iostream.h>
class string
{
char *contents;
int size;
public:
string(int sz) {
size = sz;
contents = new char[sz];
cout<<"constructor "<<size<<endl; }
~string() { delete [ ]contents;
cout<<"destructor "<<size<<endl; }
};
void main( )
{
string s1(10), s2(20);
}
/* Results:
constructor 10
constructor 20
destructor 20
destructor 10 */
以上程序中,建立对象时系统调用构造函数,在堆区内分配了一定空间;程序结束时系统删除对象,自动调用析构函数,将所分配的空间释放,退还给堆区。
从以上程序还可看出:
析构函数的调用顺序正好与构造函数的调用顺序相反。
前面提到,如已定义析构函数,则删除对象时将自动调用析构函数,因此,如对象是在一个函数或一个程序块内建立的,则在退出该函数或程序块时,将会删除该对象,从而自动地调用析构函数,见下例。
[例2] 退出程序块和函数时都删除对象,因而都调用析构函数
#include <iostream.h>
class point {
int j;
public:
point ( int i ) { j = i;
cout<<"Cons"<<j<<endl; }
~point ( ) { cout<<"Des"<<j<<endl; }
};
void main()
{
point objm(1);
{ //为教学目的而设的程序块
point objb(2);
cout<<"end of block"<<endl;
}
cout<<"end of program!"<<endl;
}
/* Results:
Cons1
Cons2
end of block
Des2
end of program!
Des1 */
还须指出,有时用户不在类中定义构造函数,但却定义了析构函数。虽然程序建立对象时系统并不调用构造函数;但在程序结束时系统自动删除对象,就会调用析构函数。
现在利用析构函数来再次了“按数值调用”和“按引用调用”时形参的不同处理方式。
在阅读下列程序之前,先熟悉一下对象用作形参和返回值的格式。我们已熟悉:
int fun( int i )
{
return i;
} 的形式。
但不熟悉:
AA fun( AA obj )
{
return obj;
} 的形式。
将两者对比一下,就容易看出,前例中形参是预定义类型int变量i,而后例中形参是class AA的对象obj。
函数调用方式,其中“按数值调用”方式将实参复制为副本并将其推入堆栈,而“按引用调用”方式则不复制实参而只将实参的指针(即地址)复制为副本并将其推入堆栈。 如果其实参是类的对象,则“按数值调用”方式将建立新的临时对象并将其推入堆栈,而“按引用调用”方式则只复制对象的指针。这点可从以下程序看出。
[例3] // destructor_3.cpp
// To differentiate between two modes: "call-by-value" and "call-by-reference"
#include <iostream.h>
class AA {
public:
int a;
AA (int x) { a = x;
cout<<"Cons-"<<a<<endl; }
~AA ( )
{ cout<<"Des-"<<a<<endl; }
};
void inc_by_value(AA obj) //形参是class AA的对象obj
{
obj.a++;
cout<<"program inc_by_value ended!"<<endl;
}
void inc_by_refer(AA & obj) //形参是class AA的对象obj的引用,实即指针
{
obj.a++;
}
void main()
{
AA obj(10);
inc_by_value(obj);
cout<<"call_by_value:a="<<obj.a<<endl;
obj.a = 20;
inc_by_refer(obj);
cout<<"call_by_reference:a="<<obj.a<<endl;
cout<<"program main ended!"<<endl;
}
/* Results:
Cons-10
program inc_by_value ended!
Des-11
call_by_value:a=10
call_by_reference:a=21
program main ended!
Des-21
*/
以上程序中定义了构造函数和析构函数。在“按数值调用”中,由系统为实参(class AA的对象)在堆栈上产生副本(也即建立新的临时对象并复制所有非静态数据),并不调用构造函数。当对函数inc_by_value( )的调用结束时,对象副本(即临时对象)被删除,从堆栈中消失,因而它的析构函数被立即调用。
而在“按引用调用”中,引用作为“别名其表,指针其实”,实参不需要产生对象副本而只产生指针副本(也即不建立临时对象)。因此在调用函数inc_by_refer( )时不须要建立临时对象,在退出函数时也不删除任何对象,也就不会调用析构函数,这种调用方式减少了空间和时间上的开销。
未完待续,转载时请表明出处:http://www.cofftech.com/thread-1395-1-1.html
欢迎大家跟帖讨论哈~~~~~
===============================================
用户所定义的析构函数主要用于释放在建立对象时构造函数从堆区中分配的空间。
和构造函数相同,只当用户在类中定义了析构函数后,程序删除对象时系统才调用析构函数。
析构函数是类的特殊成员函数,它的名字也与类名相同,只是在前面加一个符号“~”。析构函数没有任何参数,也不返回任何值。
[例1]析构函数的用途
#include <string.h>
#include <iostream.h>
class string
{
char *contents;
int size;
public:
string(int sz) {
size = sz;
contents = new char[sz];
cout<<"constructor "<<size<<endl; }
~string() { delete [ ]contents;
cout<<"destructor "<<size<<endl; }
};
void main( )
{
string s1(10), s2(20);
}
/* Results:
constructor 10
constructor 20
destructor 20
destructor 10 */
以上程序中,建立对象时系统调用构造函数,在堆区内分配了一定空间;程序结束时系统删除对象,自动调用析构函数,将所分配的空间释放,退还给堆区。
从以上程序还可看出:
析构函数的调用顺序正好与构造函数的调用顺序相反。
前面提到,如已定义析构函数,则删除对象时将自动调用析构函数,因此,如对象是在一个函数或一个程序块内建立的,则在退出该函数或程序块时,将会删除该对象,从而自动地调用析构函数,见下例。
[例2] 退出程序块和函数时都删除对象,因而都调用析构函数
#include <iostream.h>
class point {
int j;
public:
point ( int i ) { j = i;
cout<<"Cons"<<j<<endl; }
~point ( ) { cout<<"Des"<<j<<endl; }
};
void main()
{
point objm(1);
{ //为教学目的而设的程序块
point objb(2);
cout<<"end of block"<<endl;
}
cout<<"end of program!"<<endl;
}
/* Results:
Cons1
Cons2
end of block
Des2
end of program!
Des1 */
还须指出,有时用户不在类中定义构造函数,但却定义了析构函数。虽然程序建立对象时系统并不调用构造函数;但在程序结束时系统自动删除对象,就会调用析构函数。
现在利用析构函数来再次了“按数值调用”和“按引用调用”时形参的不同处理方式。
在阅读下列程序之前,先熟悉一下对象用作形参和返回值的格式。我们已熟悉:
int fun( int i )
{
return i;
} 的形式。
但不熟悉:
AA fun( AA obj )
{
return obj;
} 的形式。
将两者对比一下,就容易看出,前例中形参是预定义类型int变量i,而后例中形参是class AA的对象obj。
函数调用方式,其中“按数值调用”方式将实参复制为副本并将其推入堆栈,而“按引用调用”方式则不复制实参而只将实参的指针(即地址)复制为副本并将其推入堆栈。 如果其实参是类的对象,则“按数值调用”方式将建立新的临时对象并将其推入堆栈,而“按引用调用”方式则只复制对象的指针。这点可从以下程序看出。
[例3] // destructor_3.cpp
// To differentiate between two modes: "call-by-value" and "call-by-reference"
#include <iostream.h>
class AA {
public:
int a;
AA (int x) { a = x;
cout<<"Cons-"<<a<<endl; }
~AA ( )
{ cout<<"Des-"<<a<<endl; }
};
void inc_by_value(AA obj) //形参是class AA的对象obj
{
obj.a++;
cout<<"program inc_by_value ended!"<<endl;
}
void inc_by_refer(AA & obj) //形参是class AA的对象obj的引用,实即指针
{
obj.a++;
}
void main()
{
AA obj(10);
inc_by_value(obj);
cout<<"call_by_value:a="<<obj.a<<endl;
obj.a = 20;
inc_by_refer(obj);
cout<<"call_by_reference:a="<<obj.a<<endl;
cout<<"program main ended!"<<endl;
}
/* Results:
Cons-10
program inc_by_value ended!
Des-11
call_by_value:a=10
call_by_reference:a=21
program main ended!
Des-21
*/
以上程序中定义了构造函数和析构函数。在“按数值调用”中,由系统为实参(class AA的对象)在堆栈上产生副本(也即建立新的临时对象并复制所有非静态数据),并不调用构造函数。当对函数inc_by_value( )的调用结束时,对象副本(即临时对象)被删除,从堆栈中消失,因而它的析构函数被立即调用。
而在“按引用调用”中,引用作为“别名其表,指针其实”,实参不需要产生对象副本而只产生指针副本(也即不建立临时对象)。因此在调用函数inc_by_refer( )时不须要建立临时对象,在退出函数时也不删除任何对象,也就不会调用析构函数,这种调用方式减少了空间和时间上的开销。
发表评论
-
C++主流预处理,编译和链接过程
2011-09-11 13:26 10587在C++的程序的编写过程 ... -
c++ 一个简单的链表
2011-09-11 13:13 99541 #include <stdio.h> 2 # ... -
【2011.8.2】<C++学习笔记>预处理功能
2011-08-03 12:18 1491预处理功能介绍 ... -
C++经典电子资料下载合集
2011-07-11 11:43 36491.C++ 逆向工程 pdf高清下 ... -
《C++学习笔记》静态数据成员
2011-05-20 13:15 1117=============================== ... -
《C++学习笔记》不同数据类型对象的构造函数和析构函数的调用顺序
2011-05-19 01:34 1348=============================== ... -
《C++学习笔记》子对象构造函数和析构函数的调用顺序
2011-05-19 01:34 1508=============================== ... -
《C++学习笔记》子对象的初始化
2011-05-19 01:33 1729=============================== ... -
《C++学习笔记》特定类型数据成员的初始化
2011-05-17 10:56 1289========== ... -
《C++学习笔记》对象间非静态数据成员的复制
2011-05-16 12:04 1006=============================== ... -
《C++学习笔记》带缺省参数的构造函数(constructor with default arguments)
2011-05-16 12:03 2693=============================== ... -
《C++学习笔记》构造函数及特点
2011-05-16 12:02 1303========== ... -
《C++学习笔记》【封装性】类的接口部分与实现部分的分离
2011-05-16 11:41 1625========== ... -
《C++学习笔记》【封装性】对象及其内存存储内容
2011-05-16 11:40 831========== ... -
《C++学习笔记》【封装性】成员函数的说明和定义
2011-05-16 11:37 948成员函数可在类体之内、也可在类体之外被定义。规范的做法是将成员 ... -
《C++学习笔记》【封装】封装性
2011-05-16 11:35 711以下程序依靠封装,能 ...
相关推荐
在C++编程中,虚析构函数是一个至关重要的概念,特别是在处理对象的继承和多态性时。本文将深入探讨虚析构函数的作用、工作原理以及何时需要使用它。 首先,我们来理解什么是析构函数。析构函数是C++中的一个特殊...
C#中析构函数的详细知识点如下: 1. 析构函数定义:在C#中,析构函数通过在类的方法名前加“~”符号来定义。析构函数是一个特殊的成员函数,用于在对象生命周期结束时执行清理工作。 2. 析构函数的作用:析构函数...
在C++编程中,析构函数(Destructor)是类的一个特殊成员函数,它在对象生命周期结束时被自动调用,用于执行清理工作。这通常包括释放动态分配的内存和其他资源。学习并掌握析构函数是深入理解C++内存管理的关键。 ...
在Delphi编程中,析构函数(Destructor)是对象生命周期中的一个重要组成部分,它与构造函数(Constructor)一起确保了对象的正确初始化和销毁。析构函数主要用于清理对象在使用过程中分配的资源,如动态内存、文件...
在C++编程语言中,虚基类、虚函数成员和虚析构函数是面向对象编程中的关键概念,它们对于理解和实现多态性至关重要。多态性允许我们编写更灵活、可扩展的代码,使得程序能处理多种不同类型的对象。下面将详细解释这...
析构函数用于析构类的实例。 备注 不能在结构中定义析构函数。只能对类使用析构函数。 一个类只能有一个析构函数。 无法继承或重载析构函数。 无法调用析构函数。它们是被自动调用的。 析构函数既没有修饰符,也没有...
在C++编程语言中,虚析构函数(Virtual Destructor)是一个非常关键的概念,它主要用于处理多态性(Polymorphism)和动态类型(Dynamic Type)。本文将深入探讨虚析构函数的作用,以及为何在基类中声明虚析构函数是...
在C++编程中,析构函数(Destructor)是一个重要的概念,它负责清理对象不再需要的资源,如动态分配的内存、文件句柄等。本文将深入探讨析构函数的概念、用法以及在异常处理中的关键作用,同时对比C++与DELPHI在异常...
本次实验旨在帮助学习者深入理解并掌握C++中的构造函数与析构函数的概念及其使用方法。具体目标包括: 1. **掌握构造函数和析构函数定义方法**:了解如何在类中定义构造函数与析构函数,明确它们的作用及何时被调用...
C++析构函数 创建对象时系统会自动调用构造函数进行初始化工作,同样,销毁对象时系统也会自动调用一个函数来进行清理工作(例如回收创建对象时消耗的各种资源),这个函数被称为析构函数。 析构函数(Destructor)...
这篇介绍了析构函数,是我的读书笔记,我希望它够简短但又比较全面,起到复习的作用。如果有一些C++知识记不清楚了,它可以帮你很快回忆起来。 析构函数(destructor)的名字与类名相同,但是前面要加“~”。析构...
### 构造函数和析构函数在C++中的应用 #### 概述 构造函数与析构函数是C++编程语言中非常重要的概念...通过本篇文章的学习,我们应该能够掌握如何定义和使用构造函数与析构函数,并能在实际开发中灵活运用这些知识。
//析构函数做成员函数 }; Base::~Base()//成员函数实现 { cout<<"Base destructor"; } class Derived:public Base { public: Derived(); ~Derived(); private: int *p; }; Derived::Derived() { p=new int(0);//...
1、原因: 在实现多态时, 当用基类指针操作派生类, 在析构... Output from the destructor of class Base! << endl;}; void DoSomething() { cout << Do something in class Base! << endl;
在C++编程语言中,虚析构函数是一种特殊类型的成员函数,它的主要作用在于实现多态性,特别是在涉及动态类型和对象销毁时。本文将深入探讨虚析构函数的使用及其重要性。 首先,理解多态性是理解虚析构函数的关键。...
在C++中,析构函数的调用顺序与构造函数相反:先调用派生类的析构函数,然后逐级向上调用父类的析构函数,直至最基类的析构函数。 当我们涉及到类的继承时,构造函数和析构函数的调用顺序会变得更加复杂。例如,在...
最后,析构函数(Destructor)在C#中用于执行清理操作。与构造函数相反,析构函数在对象即将被垃圾回收之前被调用,通常用于释放非托管资源。C#的析构函数以波浪线`~`开头,且不带参数: ```csharp class Customer ...
在C++编程语言中,析构函数(Destructor)是一种特殊的成员函数,用于清理对象占用的资源或执行其他必要的清理工作,例如释放动态分配的内存。它与构造函数相对应,构造函数负责对象的创建与初始化,而析构函数则在...