第10讲 构造函数与析构函数c++
C++_构造函数与析构函数
![C++_构造函数与析构函数](https://img.taocdn.com/s3/m/414b6d2e5627a5e9856a561252d380eb62942349.png)
C++_构造函数与析构函数构造函数与析构函数1 构造函数1.1 构造函数具有⼀些特殊的性质1.2 定义构造函数的⼀般形式1.3 利⽤构造函数创建对象2 成员初始化表3 缺省参数的构造函数4 重载构造函数5 拷贝构造函数5.1 ⾃定义拷贝构造函数5.2 缺省的拷贝构造函数5.3 调⽤拷贝构造函数的三种情况5.4 浅拷贝和深拷贝6 析构函数7 调⽤构造函数和析构函数的顺序8 对象的⽣存期构造函数和析构函数都是类的成员函数,但它们都是特殊的成员函数,执⾏特殊的功能,不⽤调⽤便⾃动执⾏,⽽且这些函数的名字与类的名字有关。
C++语⾔中有⼀些成员函数性质是特殊的,这些成员函数负责对象的建⽴、删除。
这些函数的特殊性在于可以由编译器⾃动地隐含调⽤,其中⼀些函数调⽤格式采⽤运算符函数重载的语法。
C++引进⼀个⾃动完成对象初始化过程的机制,这就是类的构造函数。
对象的初始化1. 数据成员是不能在声明类时初始化2. 类型对象的初始化⽅法:1. 调⽤对外接⼝(public成员函数)实现:声明类→定义对象→调⽤接⼝给成员赋值2. 应⽤构造函数(constructor)实现:声明类→定义对象→同时给成员赋值1. 构造函数构造函数是⼀种特殊的成员函数,它主要⽤于为对象分配空间,进⾏初始化。
1.1 构造函数具有⼀些特殊的性质:(1) 构造函数的名字必须与类名相同。
(2) 构造函数可以有任意类型的参数,但不能指定返回类型。
它有隐含的返回值,该值由系统内部使⽤。
(3) 构造函数是特殊的成员函数,函数体可写在类体内,也可写在类体外。
(4) 构造函数可以重载,即⼀个类中可以定义多个参数个数或参数类型不同的构造函数。
构造函数是不能继承(5) 构造函数被声明为公有函数,但它不能像其他成员函数那样被显式地调⽤,它是在定义对象的同时被调⽤的。
(6) 在声明类时如果没有定义类的构造函数,编译系统就会在编译时⾃动⽣成⼀个默认形式的构造函数,(7) 默认构造函数是构造对象时不提供参数的构造函数。
Objective-C学习笔记---构造函数和析构函数
![Objective-C学习笔记---构造函数和析构函数](https://img.taocdn.com/s3/m/f893bd0c17fc700abb68a98271fe910ef12daee9.png)
Objective-C学习笔记---构造函数和析构函数简单的讲,构造函数就是在创建⼀个对象的时候起到初始化的作⽤,对这个对象⾥的⼀些成员变量进⾏初始化,析构函数就是在对象被删除进⾏⼀些清理⼯作,也就是专门的扫尾⼯作,下⾯⽤代码来进⾏具体说明。
⼀、构造函数 在OC中凡是已init开头的函数我们都称之为构造函数,在声明构造函数的时候,不带参数的⼀般直接声明为“-(id)init”,带参数的⼀般声明为“-(id)initWith...”。
1 @interface Person:NSObject{2 @private3 int age;4 NSString *name;5 }6 -(id)init; //不带参数的构造函数7 -(id)initWithname:(NSString *)newname age:(int)newage; //带参数的构造函数89 @end101112 @implementation Person1314 -(id)init{15 self = [super init];16 if(self){17 name = @“xiaoming”;18 age = 20;19 }20 return self;21 }2223 -(id)initWithname:(NSString *)newname age:(int)newage{24 if(self=[super init]){25 age = newage;26 name = newname;27 }28 return self;29 }30 int main(int argc, const char * argv[]) {3132 Person *p1 = [[Person alloc] init]; //对象⽣成后调⽤初始化函数33 Person *P2 = [[Person alloc] initWithnam:(NSString *)xiaohong age:19];34 //调⽤带参数的构造函数进⾏初始化35 return 0;36 }这段代码⾥,在Person类中声明了,两个初始化函数,第⼀个带参数第⼆个不带参数,在对对像进⾏初始化的时候,带参数的初始化函数显得更为灵活,⾥⾯的初始值可以⾃⼰改动。
构造函数和析构函数总论
![构造函数和析构函数总论](https://img.taocdn.com/s3/m/24dc76c433d4b14e8524686e.png)
对于相同域中的对象:先构造的后析构,后构造的先 析构。
静态(static)类成员
一、静态数据成员 1、定义: class CTest { public ; static int count ; ┆ }; CTest rect1,rect2,… //定义多个对象 注: 无论生成多少个CTest对象,只有一个count,因此它是由 所有CTest对象共有的。静态数据成员只存储一处,供所有 对象共用。静态数据成员能够实现多个对象的数据共享。
构造函数和析构函数总论
在类中可以定义两个指定功能成员函数: 构造函数 析构函数 一、 构造函数 用来生成对象,可以初始化对象的数据成 员,构造函数在有对象生成时有系统自动调用。
class crectangle { private : int left ; int right ; public : crectangle( int L, int R) //构造函数 {left=L; right=R ;} void getcoord ( int *L , int *R ) {*L=left ; *R = right } };
const对象和const成员函数
①对象定义中加入const,表示该对象为常对象, 常对象中的数据成员为常变量,不能改变该类 中任何数据成员的值,数据成员必须有初值。 常对象用来保护对象中的数据不被修改; ②类中的函数定义中加入const,表示该函数为 常成员函数,只能引用本类中的数据成员,而 不能不能改变它们。常对象只允许调用常函数。 ③类中的数据成员定义中加入const,表示该数据 成员为常数据成员,其值是不能改变的,只能 通过构造函数的成员初始化表对其进行初始化。
二.析构函数
1 、析构函数:用来释放对象,在对象 删除前,用它来做一些清理工作,它在 类对象销毁时自动调用。
C语言里面构造函数和析构函数的运用办法
![C语言里面构造函数和析构函数的运用办法](https://img.taocdn.com/s3/m/ead10fcc48649b6648d7c1c708a1284ac8500521.png)
C语言里面构造函数和析构函数的运用办法C语言里面构造函数和析构函数的运用办法摘要:构造函数与析构函数是一个类中看似较为简单的两类函数,但在实际运用过程中总会出现一些意想不到的运行错误。
本文将较系统的介绍构造函数与析构函数的原理及在C#中的运用,以及在使用过程中需要注意的若干事项。
关键字:构造函数;析构函数;垃圾回收器;非托管资源;托管资源一.构造函数与析构函数的原理作为比C更先进的语言,C#提供了更好的机制来增强程序的安全性。
C#编译器具有严格的类型安全检查功能,它几乎能找出程序中所有的语法问题,这的确帮了程序员的大忙。
但是程序通过了编译检查并不表示错误已经不存在了,在“错误”的大家庭里,“语法错误”的地位只能算是冰山一角。
级别高的错误通常隐藏得很深,不容易发现。
根据经验,不少难以察觉的程序错误是由于变量没有被正确初始化或清除造成的,而初始化和清除工作很容易被人遗忘。
微软利用面向对象的概念在设计C#语言时充分考虑了这个问题并很好地予以解决:把对象的初始化工作放在构造函数中,把清除工作放在析构函数中。
当对象被创建时,构造函数被自动执行。
当对象消亡时,析构函数被自动执行。
这样就不用担心忘记对象的初始化和清除工作。
二.构造函数在C#中的运用构造函数的名字不能随便起,必须让编译器认得出才可以被自动执行。
它的命名方法既简单又合理:让构造函数与类同名。
除了名字外,构造函数的另一个特别之处是没有返回值类型,这与返回值类型为void的函数不同。
如果它有返回值类型,那么编译器将不知所措。
在你可以访问一个类的方法、属性或任何其它东西之前,第一条执行的语句是包含有相应类的构造函数。
甚至你自己不写一个构造函数,也会有一个缺省构造函数提供给你。
class TestClass{public TestClass(): base() {} // 由CLR提供}下面列举了几种类型的构造函数1)缺省构造函数class TestClass{public TestClass(): base() {}}上面已介绍,它由系统(CLR)提供。
构造函数和析构函数的作用
![构造函数和析构函数的作用](https://img.taocdn.com/s3/m/f1ddbe3d0640be1e650e52ea551810a6f424c84d.png)
构造函数和析构函数的作用构造函数是一种特殊的成员函数,它没有返回类型,与类名相同,并且在创建对象时自动调用。
构造函数用于初始化对象的成员变量或执行一些必要的操作,确保对象的有效状态。
构造函数的主要作用如下:1.初始化成员变量构造函数用于初始化对象的成员变量。
可以通过构造函数对成员变量进行赋值操作,设置对象的初始状态。
在构造函数中可以使用this指针来访问对象的成员变量,通过this指针可以明确地指出当前对象。
2.为对象分配内存空间构造函数还负责为对象分配内存空间。
在创建对象时,构造函数会根据类的定义动态分配内存空间,保证对象的有效性,避免对象的成员变量冲突或访问越界等问题。
3.执行必要的操作构造函数还可以执行一些必要的操作,如连接数据库、初始化指针、打开文件等。
这些操作可以确保对象在创建时处于正确的状态,便于后续的使用。
4.支持函数重载构造函数支持函数重载,即在同一个类中可以定义多个构造函数,根据参数的不同进行区分。
这样可以方便地根据需要创建不同类型或不同初始状态的对象。
5.构造函数链在一些情况下,可以通过构造函数链来避免重复的代码。
构造函数链是指一个构造函数调用另一个构造函数来完成一部分初始化工作。
通过构造函数链,可以简化代码,并确保对象被正确初始化。
总之,构造函数的主要作用是为对象分配内存空间、初始化成员变量、执行必要的操作,确保对象的有效状态。
析构函数是与构造函数对应的一种特殊成员函数,用于清理对象内的资源并进行析构操作。
析构函数在对象销毁时自动调用,与构造函数相反。
析构函数的主要作用如下:1.释放动态分配的内存空间析构函数负责释放动态分配的内存空间,确保对象销毁时资源能够被正确释放。
如果在构造函数中动态分配了内存,应该在析构函数中释放,避免内存泄漏。
2.断开与外部资源的连接析构函数还可以断开与外部资源的连接,如关闭数据库连接、关闭文件等。
这样可以避免资源的浪费和异常。
3.执行必要的清理操作析构函数还可以执行一些必要的清理操作,如释放锁、关闭线程等。
C#类的构造函数与析构函数
![C#类的构造函数与析构函数](https://img.taocdn.com/s3/m/3ca3c5bf65ce0508763213e6.png)
C#类的构造函数与析构函数1.构造函数:类的构造函数是用来创建类的一个实例。
创建一个实例的一般形式:类名实例名= new 类名(构造函数参数列表);构造函数和类中其他函数相比,是较为特殊的,它的名称必须和类同名。
定义一个构造函数的一般形式是:Class 类名{类名(参数表);//就是定义构造函数{//语句}}例子:using System;class MyClass{MyClass(){Console.WriteLine("启动构造函数");Console.ReadLine();}public static void Main(){MyClass cM = new MyClass();}}运行结果:MyClass()就是一个构造函数,构造函数是没有任何返回值的。
构造函数也可以携带参数,看下面的例子:using System;class userName{string Uname;//定义一个带参数的构造函数public userName(string name){Console.WriteLine("新建一个用户:");Uname = name;}public void ShowName(){Console.WriteLine("用户名是:"+ Uname); }public static void Main(){//用带参数的构造函数创建类的一个实例userName uN1 = new userName("zhanghua"); uN1.ShowName();Console.ReadLine();}}运行结果:2.析构函数定义一个析构函数的一般形式是:Class 类名{~类名(参数表);//定义析构函数{//语句}}析构函数的使用:using System;class First{public First(){Console.WriteLine("First's constructor is called");}~First(){Console.WriteLine("First's destructor is called");}}class Second{public Second(){Console.WriteLine("Sencond's constructor is called");}~Second(){Console.WriteLine("Second's destructor is called");}}class Third{public Third(){Console.WriteLine("Third's constructor is called");}~Third(){Console.WriteLine("Third's destructor is called");}}public class MainClass{public static void Main(){First myObject1 = new First();Second myObject2 = new Second();Third myObject3 = new Third();}}运行结果:。
c++程序设计教程 第十章 构造函数和析构函数
![c++程序设计教程 第十章 构造函数和析构函数](https://img.taocdn.com/s3/m/73380290915f804d2a16c1b6.png)
10.1.2 构造函数重载
在一个类中可以定义多个构造函数,以便对类 对象提供不同的初始化方法。这些构造函数的函数 名完全相同,都没有返回值,而参数的类型或参数 的个数各不相同。对于一般的重载函数,系统是根 据参数列表来决定调用哪个函数,对重载的构造函 数而言,系统是根据创建对象时提供的参数来确定 调用哪个构造函数来初始化对象的。
return s;
4
}
2.使用参数初始化列表的构造函数
使用参数初始化列表的构造函数的形式为:
类名::构造函数名(<形参1,形参2,……>)<:数据成员1(形参1),数据成员2(形参2 ),………>
{函数体} 例10.1 中定义类Tri 的构造函数可以写成如下形式:
Tri(double x , double y , double z ):a(x),b(y),c(z){}
return s;
cout<<"Tria的周长"<<Tria.Peri()<<endl;
}
cout<<"tria的面积为: "<<tria.Area()<<endl;
};
}
7
10.1.3 默认的构造函数
默认的构造函数又称缺省的构造函数,有两种形式:
(1)参数为缺省值的构造函数,如在类体中说明以下形式 的构造函数:
函数,并不是用函数名调用的,而是隐式调用的
2
定义构造函数的两种方法
构造函数有不带参数的和带参数的两种,其定义的 形式都是一致的。 1.在构造函数体内对数据成员赋值: 在类体中定义构造函数的形式如下: 类名(<形参1,形参2,……>) {函数体} 其中,尖括号< >中的内容可以省略。
[学习C++]构造函数 析构函数和赋值操作符
![[学习C++]构造函数 析构函数和赋值操作符](https://img.taocdn.com/s3/m/94f9b34d2b160b4e767fcfa3.png)
几乎所有的类都有一个或多个构造函数,一个析构函数和一个赋值操作符。
这没什么奇怪的,因为它们提供的都是一些最基本的功能。
构造函数控制对象生成时的基本操作,并保证对象被初始化;析构函数摧毁一个对象并保证它被彻底清除;赋值操作符则给对象一个新的值。
在这些函数上出错就会给整个类带来无尽的负面影响,所以一定要保证其正确性。
本章我将指导如何用这些函数来搭建一个结构良好的类的主干。
构造函数,析构函数和赋值操作符几乎所有的类都有一个或多个构造函数,一个析构函数和一个赋值操作符。
这没什么奇怪的,因为它们提供的都是一些最基本的功能。
构造函数控制对象生成时的基本操作,并保证对象被初始化;析构函数摧毁一个对象并保证它被彻底清除;赋值操作符则给对象一个新的值。
在这些函数上出错就会给整个类带来无尽的负面影响,所以一定要保证其正确性。
本章我将指导如何用这些函数来搭建一个结构良好的类的主干。
条款11: 为需要动态分配内存的类声明一个拷贝构造函数和一个赋值操作符看下面一个表示string对象的类:// 一个很简单的string类class string {public:string(const char *value);~string();... // 没有拷贝构造函数和operator=private:char *data;};string::string(const char *value){if (value) {data = new char[strlen(value) + 1];strcpy(data, value);}else {data = new char[1];*data = '\0';}}inline string::~string() { delete [] data; }请注意这个类里没有声明赋值操作符和拷贝构造函数。
这会带来一些不良后果。
如果这样定义两个对象:string a("hello");string b("world");其结果就会如下所示:a: data——> "hello\0"b: data——> "world\0"对象a的内部是一个指向包含字符串"hello"的内存的指针,对象b的内部是一个指向包含字符串"world"的内存的指针。
c++ 构造函数与析构函数
![c++ 构造函数与析构函数](https://img.taocdn.com/s3/m/98b47fc8da38376baf1faedc.png)
• 只要一个类定义了一个构造函数(不一定 只要一个类定义了一个构造函数( 是无参构造函数), ),C++编译系统就不再 是无参构造函数), 编译系统就不再 提供默认的构造函数。 提供默认的构造函数。
析构函数
• 当一个对象被定义时,系统自动调用构造函数为 当一个对象被定义时, 该对象分配相应的资源,当对象使用完毕后, 该对象分配相应的资源,当对象使用完毕后,这 些系统资源需要在对象消失前被释放。 些系统资源需要在对象消失前被释放。 • 析构函数的定义方式为: 析构函数的定义方式为:
– 一个类中只能拥有一个析构函数。 一个类中只能拥有一个析构函数。 – 对于一个简单的类来说,大多可以直接使用系 对于一个简单的类来说, 统提供的默认析构函数。 统提供的默认析构函数。
• 但是,如果在类的对象中分配有动态内存(如:用 但是,如果在类的对象中分配有动态内存( new申请分配的内容)时,就必须为该类提供适当 申请分配的内容) 申请分果: 结果:
拷贝构造函数
• 拷贝构造函数
– 是C++中引入的一种新的构造函数。 中引入的一种新的构造函数。 中引入的一种新的构造函数 – 其作用是使用一个已经存在的对象(有拷贝构造函 其作用是使用一个已经存在的对象( 使用一个已经存在的对象 数的形参提供),去初始化一个新创建的对象 数的形参提供),去初始化一个新创建的对象 ),
• 例子: 类person包括 个数据成员,用来记录人员信 例子: 包括4个数据成员 包括 个数据成员, 生成对象obj,并使用构造函数为 息。生成对象 ,并使用构造函数为obj赋予初始值 赋予初始值
#include <iostream> class Person //定义类 { private: //类Person的数据成员 char name[10]; //姓名 int age; //年龄 int salary; //薪金 char tel[20]; //电话 public: //构造函数Person Person( char *xname, int xage, int xsalary, char *xtel); void disp (); };
c语言构造函数
![c语言构造函数](https://img.taocdn.com/s3/m/a2baf3df541810a6f524ccbff121dd36a32dc4bb.png)
c语言构造函数一、概述C语言是一种高级编程语言,它支持面向对象编程。
在C++中,我们可以使用构造函数来初始化对象的数据成员。
但是,在C语言中并没有直接支持构造函数的语法,因此我们需要自己实现构造函数。
二、什么是构造函数?在C++中,构造函数是一种特殊的成员函数,它用于初始化类的对象。
当创建一个类的对象时,构造函数会被调用来初始化这个对象的数据成员。
在C语言中,我们可以使用结构体来模拟类,并且可以使用指向结构体的指针来模拟对象。
因此,在C语言中实现构造函数就变得十分重要。
三、如何实现构造函数?在C语言中,我们可以通过以下两种方式来实现构造函数:1. 使用工厂方法工厂方法是一种创建对象的设计模式。
它将对象的创建过程封装在一个工厂类中,并通过调用工厂方法来创建对象。
在C语言中,我们可以定义一个结构体作为类,并定义一个工厂方法来创建这个结构体的实例。
例如:```typedef struct {int x;int y;} Point;Point* create_point(int x, int y) {Point* p = (Point*)malloc(sizeof(Point));p->x = x;p->y = y;return p;}```2. 在结构体中定义初始化函数在C语言中,我们也可以在结构体中定义一个初始化函数来实现构造函数的功能。
例如:```typedef struct {int x;int y;void (*init)(Point*, int, int);} Point;void init_point(Point* p, int x, int y) {p->x = x;p->y = y;}Point p1 = {0, 0, init_point};p1.init(&p1, 1, 2);```四、结论通过以上两种方式,我们可以在C语言中实现类似于C++中的构造函数的功能。
C 反汇编与逆向分析技术揭秘
![C 反汇编与逆向分析技术揭秘](https://img.taocdn.com/s3/m/d16e35180166f5335a8102d276a20029bd6463bf.png)
3.1程序的真正入口 3.2了解VC++6.0的启动函数 3.3 main函数的识别 3.4本章小结
4.1算术运算和赋值 4.2关系运算和逻辑运算 4.3位运算 4.4编译器使用的优化技巧 4.5一次算法逆向之旅 4.6本章小结
5.1 if语句 5.2 if……else……语句 5.3用if构成的多分支流程 5.4 switch的真相 5.5难以构成跳转表的switch 5.6降低判定树的高度 5.7 do/while/for的比较 5.8编译器对循环结构的优化 5.9本章小结
9.1对象的内存布局 9.2 this指针 9.3静态数据成员 9.4对象作为函数参数 9.5对象作为返回值 9.6本章小结
10.1构造函数的出现时机 10.2每个对象都有默认的构造函数吗 10.3析构函数的出现时机 10.4本章小结
11.1虚函数的机制 11.2虚函数的识别 11.3本章小结
目录分析
第一部分准备工作
1.1调试工具Microsoft Visual C++6.0和OllyDBG 1.2反汇编静态分析工具IDA 1.3反汇编引擎的工作原理 1.4本章小结
第2章基本数据类型 的表现形式
第3章认识启动函数, 找到用户入口
第4章观察各种表达 式的求值过程
第5章流程控制语句 的识别
第16章调试器 OllyDBG的工作原理 分析
第17章反汇编代码的 重建与编译
14.1开发环境的识别 14.2开发环境的伪造 14.3本章小结
15.1调试环境配置 15.2病毒程序初步分析 15.3 “熊猫烧香”的启动过程分析 15.4 “熊猫烧香”的自我保护分析 15.5 “熊猫烧香”的感染过程分析 15.6本章小结
析构函数和构造函数调用顺序
![析构函数和构造函数调用顺序](https://img.taocdn.com/s3/m/2a6894861b37f111f18583d049649b6648d70912.png)
析构函数和构造函数调用顺序构造函数和析构函数是面向对象编程中常用的两个概念,它们在对象的创建和销毁过程中起着重要的作用。
本文将分别介绍构造函数和析构函数的调用顺序。
一、构造函数的调用顺序构造函数是在对象创建时被调用的特殊成员函数,用于初始化对象的数据成员。
在创建对象时,编译器会自动调用构造函数。
1. 默认构造函数如果类没有定义任何构造函数,编译器会自动生成一个默认构造函数。
默认构造函数不接受任何参数,仅进行默认的初始化操作。
当创建对象时,会首先调用默认构造函数。
2. 带参数的构造函数如果类定义了带参数的构造函数,那么在创建对象时,可以通过传递参数来调用相应的构造函数。
如果定义了多个带参数的构造函数,编译器会根据实际传递的参数类型和个数来选择调用哪个构造函数。
3. 派生类构造函数调用顺序如果类是派生类,它的构造函数在创建对象时会先调用基类的构造函数,然后再调用自身的构造函数。
这是因为派生类的对象包含了基类的成员,所以需要先初始化基类的成员,再初始化自身的成员。
二、析构函数的调用顺序析构函数是在对象销毁时被调用的特殊成员函数,用于释放对象所占用的资源。
在对象销毁时,编译器会自动调用析构函数。
1. 默认析构函数如果类没有定义任何析构函数,编译器会自动生成一个默认析构函数。
默认析构函数不做任何操作。
当销毁对象时,会首先调用默认析构函数。
2. 派生类析构函数调用顺序如果类是派生类,它的析构函数在销毁对象时会先调用自身的析构函数,然后再调用基类的析构函数。
这是因为派生类的对象的成员在内存中的布局是先基类的成员,然后是自身的成员,所以需要先释放自身的成员,再释放基类的成员。
三、构造函数和析构函数的调用顺序总结1. 构造函数的调用顺序是先调用基类的构造函数,然后再调用派生类的构造函数。
2. 析构函数的调用顺序是先调用派生类的析构函数,然后再调用基类的析构函数。
3. 构造函数和析构函数的调用顺序与对象的创建和销毁顺序相反。
类、构造函数、析构函数
![类、构造函数、析构函数](https://img.taocdn.com/s3/m/4387871f227916888486d760.png)
类:1、在类体中不允许对所定义的数据成员进行初始化。
2、类的成员函数描述类所表达的问题的行为。
类中所有的成员函数都必须在类体内进行说明。
但成员函数的定义既可以在类体内给出,也可以在类体外给出。
第一种方式是将成员函数直接定义在类的内部。
第二种方式是在类声明中给出对成员函数的说明,而在类外部对成员函数进行定义(但成员函数仍然在类范围内)。
这种在类外部定义的成员函数的一般格式是:<返回类型><类名>::<成员函数名>(<参数表>){<函数体>}在类体外定义成员函数时,要注意必须在成员函数名前加上类名和作用域运算符(::)。
作用域运算符用来标识某个成员属于某个类。
作用域运算符的使用格式如下:<类名>::<成员函数名>(<参数表>)或<类名>::<数据成员名>成员函数的两种定义方式之间是有差别的。
如果一个成员函数的声明和定义都在类体内,那么这个成员函数就是内联函数。
如果一个成员函数的声明在类体内,而定义在类体外,这时对该成员函数的调用是按一般函数进行的。
如果要将定义在类体外的成员函数也作为内联函数处理,就必须在成员函数的定义前加上关键字“inline”,以此显式地说明该成员函数也是一个内联函数。
成员函数除了可以定义为内联函数以外,也可以进行重载,可以对其参数设置默认值。
6.3 构造函数和析构函数1、构造函数和析构函数的定义。
构造函数的作用是在对象被创建时利用特定的值构造对象,将对象初始化为一种特定的状态,使该对象具有区别于其他对象的特征。
构造函数在对象被创建的时候由系统自动调用。
构造函数也是类的成员函数,但它是一种特殊的成员函数,它除了具有一般成员函数的特性之外,还具有一些特殊的性质:(1)构造函数的名字必须与类名相同;(2)构造函数不指定返回类型,它隐含有返回值,由系统内部使用;(3)构造函数可以有一个或多个参数,因此构造函数可以重载;(4)在创建对象时,系统会自动调用构造函数。
2、缺省构造函数和缺省析构函数缺省构造函数就是调用时不必提供参数的构造函数。
构造函数和析构函数和复制构造函数
![构造函数和析构函数和复制构造函数](https://img.taocdn.com/s3/m/13504f9fdaef5ef7ba0d3caa.png)
实验五【实验内容】构造函数和析构函数和复制构造函数构造函数1. 构造函数是类的一个特殊成员函数,它的函数名与类名相同。
2. 构造函数定义了对象数据成员的初始化方法,它只在创建对象时被系统自动调用,并且只在创建对象时调用一次,是为创建的对象分配内存空间和对数据成员进行初始化。
3. 构造函数无函数类型,没有返回值,一般都声明为公有函数。
4.C++规定,每个类必须有构造函数,没有构造函数就不能创建对象。
5.如果程序中未声明构造函数,则系统自动产生出一个默认形式的构造函数,如果提供了一个构造函数,系统就不能自动提供一个默认的构造函数。
6.构造函数可以重载,即可以定义多个参数及参数类型不同的构造函数。
复制构造函数又称拷贝构造函数,是一种特殊的构造函数,其形参为本类的对象引用。
功能是把初始值对象的每个数据成员的值都复制到新建立的对象。
如果程序员没有为类声明拷贝初始化构造函数,则编译器自己生成一个拷贝构造函数。
1. 当用类的一个对象去初始化该类的另一个对象时系统自动调用它实现拷贝赋值。
2. 若函数的形参为类对象,调用函数时,实参赋值给形参,系统自动调用拷贝构造函数。
3. 当函数的返回值是类对象时,系统自动调用拷贝构造函数。
析构函数析构函数也是特殊的类成员函数,它没有返回类型,没有参数,不能随意调用,也没有重载,只有在类的生命周期结束的时候,由系统自动调用。
析构函数和构造函数的最主要的区别:调用期不同、构造函数可以有参数可以重载。
实验1设计一个学生类stu,其中含有数据成员name、english和math,分别表示学生的姓名、英语成绩与数学成绩,使用类的成员函数output 和total输出学生的基本信息和总成绩,并完成在main函数中的相应调用。
#include <iostream>using namespace std;class stu{public:stu(char n[]="",double e=0.0,double m=0.0);~stu();void input();void output();void total();private:char name[8];double english,math;};stu::stu(char n[],double e,double m){strcpy(name,n);english=e;math=m;}stu::~stu(){}void stu::input(){cout<<"请输入学生的姓名、英语成绩与数学成绩:"<<endl;cin>>name>>english>>math;}void stu::output (){cout<<"学生的姓名、英语成绩与数学成绩:"<<name<<","<<english<<","<<math<<endl;}void stu::total (){cout<<"学生的总成绩是:"<<english+math<<endl;}void main(){stu s1("张思宁",95,80),s2;s2.input ();s1.output ();s1.total ();s2.output() ;s2.total ();}实验2练习书上112页例4-2,熟悉复制构造函数被调用的3种情况。
c语言构造函数和析构函数
![c语言构造函数和析构函数](https://img.taocdn.com/s3/m/733b8c308f9951e79b89680203d8ce2f006665df.png)
c语言构造函数和析构函数C语言构造函数和析构函数构造函数和析构函数是面向对象编程(OOP)中的重要概念。
它们用于在对象的创建和销毁过程中执行特定的操作。
然而,在C语言中并没有内置的构造函数和析构函数的概念,因为C语言不直接支持面向对象编程。
然而,我们可以通过一些技巧来模拟构造函数和析构函数的行为。
本文将逐步解释如何实现这些概念,并探讨构造函数和析构函数在C语言中的应用。
第一步:模拟构造函数构造函数在对象创建时被自动调用,用于初始化对象的成员变量。
在C语言中,我们可以通过在函数中手动分配内存并初始化对象来模拟构造函数的行为。
首先,我们需要定义一个结构体来表示我们要创建的对象。
结构体可以包含多个成员变量,每个成员变量代表对象的一个属性。
例如,我们可以创建一个学生对象,其中包含姓名和年龄两个成员变量。
ctypedef struct {char name[20];int age;} Student;接下来,我们可以编写一个创建学生对象的函数,该函数将分配内存并初始化学生对象的成员变量。
cStudent* createStudent(char* name, int age) {Student* student = (Student*)malloc(sizeof(Student));strcpy(student->name, name);student->age = age;return student;}在上述代码中,我们使用malloc函数分配了一块内存,大小足够容纳一个Student结构体。
然后,我们使用strcpy函数将传入的姓名参数复制到student对象的name成员变量中,使用赋值运算符初始化age成员变量。
最后,我们将指向新创建的学生对象的指针返回。
现在,我们可以调用createStudent函数来创建一个学生对象,并访问其成员变量。
cint main() {Student* student = createStudent("Tom", 20);printf("Name: s, Age: d\n", student->name,student->age);free(student);return 0;}在上述代码中,我们首先调用createStudent函数来创建一个学生对象,并将返回的指针赋给student指针。
C++复习5大基础函数(析构函数、构造函数、内联函数、拷贝构造函数、友元函数)详解
![C++复习5大基础函数(析构函数、构造函数、内联函数、拷贝构造函数、友元函数)详解](https://img.taocdn.com/s3/m/f0c8f1dcafaad1f34693daef5ef7ba0d4a736d1c.png)
1、析构函数2、构造函数3、内联函数4、拷贝构造函数5、友元函数1、析构函数是类的一种特殊的成员函数,它会在每次删除所创建的对象时执行。
析构函数的名称与类的名称是完全相同的,只是在前面加了个波浪号(~)作为前缀,它不会返回任何值,也不能带有任何参数。
析构函数有助于在跳出程序(比如关闭文件、释放内存等)前释放资源。
2、构造函数是类的一种特殊的成员函数,它会在每次创建类的新对象时执行。
构造函数的名称与类的名称是完全相同的,并且不会返回任何类型,也不会返回void。
构造函数可用于为某些成员变量设置初始值。
3、内联函数有时称作在线函数(inline)。
函数的调用是需要付出一定的时空开销的,因为系统在调用函数时,要保留现场,然后转入被调用函数去执行,调用完,再返回主调函数,此时再恢复现场,这些操作。
所谓“内联函数”就是将很简单的函数“内嵌”到调用他的程序代码中,只样做的目的是为了节约下原本函数调用时的时空开销。
但必须注意的是:作为内联函数,函数体必须十分简单,不能含有循环、条件、选择等复杂的结构,否则就不能做为内联函数了。
事实上,即便你没有指定函数为内联函数,有的编译系统也会自动将很简单的函数作为内联函数处理;而对于复杂的函数,即便你指定他为内联函数,系统也不会理会的。
内联函数也有一定的局限性。
就是函数中的执行代码不能太多了,如果,内联函数的函数体过大,一般的编译器会放弃内联方式,而采用普通的方式调用函数。
这样,内联函数就和普通函数执行效率一样了。
4、拷贝构造函数拷贝构造函数,又称复制构造函数。
复制构造函数是一种特殊的构造函数,函数的名称必须和类名称一致,它必须的一个参数是本类型的一个引用变量。
它在创建对象时,是使用同一类中之前创建的对象来初始化新创建的对象.为什么需要拷贝构造函数?把参数传递给函数有三种方法,一种是传值,一种是传地址,一种是传引用。
传值与其他两种方式不同的地方在于当使用传值方式的时候,会在函数里面生成传递参数的一个副本,这个副本的内容是按位从原始参数那里复制过来的,两者的内容是相同的。
跟我学VS#语言编程技术——C#语言中的构造函数及析构函数应用示例
![跟我学VS#语言编程技术——C#语言中的构造函数及析构函数应用示例](https://img.taocdn.com/s3/m/9227f4036bd97f192279e942.png)
Derived obj=new Derived(10,20); } } (9)类中的成员变量声明并初始化: 1)C#支持变量的声明并初始化,此时将被编译器转换成赋值语句强加在类的每一个构造 函数的内部。并且初始化语句在父类构造函数的调用之前,最后执行的才是本构造函数内的 语句。也就是说变量初始化的优先权是最高的。 2)通过声明出 private 构造函数以禁止创建出该类的对象(常用于类中的成员全部为 static 的类,如 Console、Math 等类)。 2、析构函数 (1)定义 函数名与类名重名且以~开头的无任何的返回值和形参定义的成员函数。定义的语法:
杨教授工作室,版权所3有,盗版必究, 3/6 页
杨教授工作室 精心创作的优秀程序员 职业提升必读系列资料
Console.WriteLine("初始化基类的参数"); } } class Derived :BaseA{ public Derived(int x, int y) :base(){
//将产生编译错误,因为在基类中没有定义无参数的构造函数 } public Derived(int x, int y) :base(x,y) {
}
public Circle(int x, int y,double r){
X0=x; Y0=y; R=100.0;
}
}
public class Test{
public static void Main(){
Circle C1=new Circle(); //调用无参数的构造函数 Circle C2=new Circle(150,150); //调用两个 int 参数的构造函数 Circle C3=new Circle(150,150.0); //调用两个参数的构造函数 Circle C4=new Circle(150,150,150.0); //调用三个参数的构造函数
《C语言程序设计教程》全册教案教学设计
![《C语言程序设计教程》全册教案教学设计](https://img.taocdn.com/s3/m/a6e41a9bdb38376baf1ffc4ffe4733687e21fc8d.png)
《C语言程序设计教程》全册教案完整版教学设计第一章:C语言概述1.1 教学目标让学生了解C语言的历史和发展背景让学生掌握C语言的特点和优势让学生了解C语言的应用领域1.2 教学内容C语言的历史和发展背景C语言的特点和优势C语言的应用领域1.3 教学方法讲解法:讲解C语言的历史和发展背景,讲解C语言的特点和优势讨论法:引导学生讨论C语言的应用领域1.4 教学评价课后作业:让学生编写简单的C语言程序,了解C语言的基本语法第二章:C语言基础语法2.1 教学目标让学生掌握C语言的基本语法,包括数据类型、运算符、表达式等让学生了解C语言的控制语句,包括条件语句、循环语句等2.2 教学内容数据类型、变量和常量运算符和表达式控制语句:条件语句、循环语句2.3 教学方法讲解法:讲解数据类型、变量和常量的定义和使用,讲解运算符和表达式的使用,讲解条件语句和循环语句的语法和功能编程实践:让学生编写C语言程序,运用所学的控制语句2.4 教学评价课后作业:让学生编写C语言程序,运用所学的数据类型、运算符和控制语句第三章:函数与编译预处理3.1 教学目标让学生掌握C语言的函数概念和定义方法让学生了解C语言的编译预处理指令3.2 教学内容函数的定义和声明编译预处理指令:include、define、宏定义和宏调用3.3 教学方法讲解法:讲解函数的定义和声明的语法和功能,讲解编译预处理指令的使用方法编程实践:让学生编写C语言程序,运用所学的函数和编译预处理指令3.4 教学评价课后作业:让学生编写C语言程序,运用所学的函数和编译预处理指令第四章:数组和字符串4.1 教学目标让学生掌握C语言的数组和字符串的概念和使用方法4.2 教学内容一维数组的定义和使用字符串的定义和使用4.3 教学方法讲解法:讲解一维数组的定义和使用的语法和功能,讲解字符串的定义和使用的语法和功能编程实践:让学生编写C语言程序,运用所学的数组和字符串4.4 教学评价课后作业:让学生编写C语言程序,运用所学的数组和字符串第五章:指针5.1 教学目标让学生掌握C语言的指针的概念和使用方法5.2 教学内容指针的概念和声明指针的赋值和使用指针与数组指针与函数5.3 教学方法讲解法:讲解指针的概念和声明的语法和功能,讲解指针的赋值和使用的语法和功能,讲解指针与数组和指针与函数的关系编程实践:让学生编写C语言程序,运用所学的指针知识5.4 教学评价课后作业:让学生编写C语言程序,运用所学的指针知识第六章:结构体、联合体和枚举6.1 教学目标让学生掌握C语言中的结构体、联合体和枚举的概念和使用方法。
析构函数的特点如下
![析构函数的特点如下](https://img.taocdn.com/s3/m/e78bbd6033687e21af45a9ee.png)
构造函数的特点
存在性
➢ 每一个对象必须要有与之对应的构造函数 ➢ 所有的对象在定义时,必须调用构造函数 ➢ 不存在没有构造函数的对象
唯一性
➢ 任一对象调用的构造函数必须唯一
14
构造函数的特点
缺省的构造函数
➢ 若无显式定义构造函数,系统产生默认缺省构造函数 ➢ 若已显式定义构造函数,系统不产生默认缺省构造函数
由于构造函数属于类的成员函数,它对私 有数据成员、保护的数据成员和公有的数 据成员均能进行初始化。
8
构造函数
属性
构造函数
目的
类的公有成员函数
实现
实现成员数据初始化
私有数据成员
保护数据成员
公有数据成员
9
例1:
class A
{
构造函数,
float x,y;
初始化对象
public:
A(float a,float b){ x=a; y=b;}//
3
构造函数的引入
class A { float x,y;
public:
如何实现对象成员数 据的快速初始化?
float m,n;
void Setxy( float a, float b ){ x=a; y=b; }
void Print(void) { cout<<x<<‘\t’<<y<<endl; }
};
void main(void)
{ A a1; 两个构造函数均可供调用,构造函数不唯一
A a2(3.0,30.0);
}
21
动态建立对象时的构造函数
1
2
3
4
STEP
解构函数 析构函数
![解构函数 析构函数](https://img.taocdn.com/s3/m/dd719e184a35eefdc8d376eeaeaad1f34693118c.png)
解构函数析构函数解构函数和析构函数是面向对象编程中非常重要的概念,它们分别用于创建对象和销毁对象时执行特定的操作。
本文将详细介绍解构函数和析构函数的概念、作用、语法和使用方法。
一、概念1. 解构函数(Constructor)解构函数是一种特殊的成员函数,它在创建对象时被调用,用于初始化对象的成员变量。
解构函数的名称与类名相同,没有返回值,也不需要显式地调用。
2. 析构函数(Destructor)析构函数是一种特殊的成员函数,它在对象被销毁时自动调用,用于释放对象占用的资源。
析构函数的名称与类名相同,前面加上一个波浪号(~),没有参数和返回值。
二、作用1. 解构函数的作用解构函数用于初始化对象的成员变量,可以进行一些必要的初始化操作,例如为成员变量分配内存、初始化默认值等。
解构函数在对象创建时自动调用,确保对象的数据成员处于合理的初始状态。
2. 析构函数的作用析构函数用于释放对象占用的资源,例如释放动态分配的内存、关闭打开的文件、释放网络连接等。
析构函数在对象被销毁时自动调用,确保对象占用的资源被正确释放,避免内存泄漏和资源浪费。
三、语法1. 解构函数的语法解构函数没有返回值,不需要显式调用,其语法格式如下:```类名() {// 构造函数的代码逻辑}```2. 析构函数的语法析构函数没有返回值,不需要显式调用,其语法格式如下:```~类名() {// 析构函数的代码逻辑}```四、使用方法1. 解构函数的使用方法解构函数的使用方法很简单,在创建对象时会自动调用解构函数进行初始化操作。
在解构函数中,可以根据需要对成员变量进行初始化,例如分配内存、设置默认值等。
2. 析构函数的使用方法析构函数的使用方法也很简单,在对象被销毁时会自动调用析构函数进行资源释放操作。
在析构函数中,可以根据需要释放对象占用的资源,例如释放内存、关闭文件、断开网络连接等。
五、示例代码为了更好地理解解构函数和析构函数的使用方法,下面给出一个简单的示例代码:```cpp#include <iostream>using namespace std;class MyClass {public:MyClass() {cout << "Constructor called!" << endl;// 初始化操作}~MyClass() {cout << "Destructor called!" << endl;// 资源释放操作}};int main() {MyClass obj; // 创建对象时会自动调用解构函数进行初始化// 其他操作return 0;}```在上面的示例代码中,定义了一个名为MyClass的类,其中包含了一个解构函数和一个析构函数。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
对象的创建
对象初始化
这样会带来一些问题: 对象的初始化可以显式调用set之类成员函数来完成, 忘记设置会带来严重后果(设置前,对象的数据是存 储单元的遗留值,毫无意义); 对象的创建、初始化人为地划分为两个阶段,不符 合客观现实(客观现实是:对象的属性与生俱来) ……
问题的解决:
构造函数 (自动完成: 对象的创建 + 初始化工作)
Student st(123456, 1980,12,3); //定义Student类对象 st.display(); //显示学生st信息
3. 重载构造函数
(1)与普通函数一样,构造函数也可以重载(即一个 类中允许有多个同名的构造函数存在),系统会根 据参数个数、参数类型、参数顺序的不同,选择其 中的一个构造函数进行对象的创建、初始化。 例子见 教材p267 [例 9.3] 课件【例3-3】:重载日期类的例子.doc (2)构造函数也可以具有默认参数 例子见 教材p269 [例 9.4]
4. 析构函数 (Destructor)
(1)析构函数的作用
在前面我们提到了析构函数的作用:在对象消
亡时,自动完成清除工作。
析构函数存在的必要性: (通过二个例子来说明) 如果构造函数中使用了new 命令申请了堆空间,在对象 撤消时,就要用delete命令归还对象所占空间。否则, 造成内存泄漏。 退出程序时,进行文件内容检查,提示存盘操作 。 这些工作都 可以通过析构 函数来完成。
对象的创建 例如: Date today, tomorrow; ……
设置对象值 (对象初始化) 例如: today.SetDate( 2008,9,16); ……
每一个对象 有自己的生命周期
对象的使用 ……
对象的结束 (与变量一样,对象也 有自己的生命周期)
从上可以看到:对象的创建与初始化过程是分开的
结论:
(临终遗言) 自动调用析构函数完 成
构造函数的作用:对象的创建、初始化工作(自动完成) 析构函数的作用:对象消亡时的清除工作(自动完成)
(2)构造函数的性质
构造函数是一种特殊的成员函数,除具有一般成 员函数的特性外,还具有如下特殊性质:
构造函数的函数名必须与其类名相同; 不包含任何返回类型,甚至void类型; 一个类可以有多个构造函数(即构造函数重载),也可以没有 构造函数(在这种情况下,系统会自动为类创建一个默认构 造函数); 构造函数可以有参数,也可以没有参数(默认的构造函数不 带参数或全部参数为默认值); 在创建对象时,系统会自动调用构造函数(例:执行 Person abc; 语句时就自动调用了构造函数),且只调用一次;
本讲小结 构造函数:作用、性质、默认构造函数; 带参数构造函数:一般格式、用参数初始化 表初始化数据成员、类成员的初始化、对象 定义的格式;
重载构造函数、带默认值参数的构造函数; 析构函数:作用、性质、调用顺序; 构造函数与析构函数的调用顺序。
(2)用参数初始化表对数据成员初始化 格式: 构造函数名(形参表):数据成员1(参数1),…, 数据成员n(参数n) { } //这一对大括号不能省略 优点:书写简便
用这种方法改写前面的例子: class Date { public: Date(int y, int m, int d) : year(y), month(m), day(d) { } … }; //定义对象 Date today(2006,9,18), tomorrow(2006,9,19);
(3)类成员的初始化
C++还允许用另外一个已知类的对象作为类的数 据成员,这称为类的嵌套。要先用参数初象)的构造函数首先被调用。
假设已声明了Date类: class Date { public: //带参数的构造函数 Date(int y, int m, int d) : year(y),month(m),day(d) { cout<<"Date类构造函数被调用!"<<endl; } …… };
通常,设为public类型。
【例3-1】:构造函数例子(Person类)
摘选内容: class Person { private: … public: Person( ); … }; Person::Person( ) { … }
//不带参数的构造函数
//构造函数的类外定义
(3)默认构造函数(又称为缺省构造函数)
1000
5.构造函数与析构函数的调用顺序
构造函数调用顺序:按照对象定义的先后顺序调用 构造函数,以创建新对象; 析构函数调用顺序:先创建的对象后被析构,后创 建的对象先被析构。(与构造函数的调用顺序正好相 反) 教材p272 [例 9.5]中对象的构造、析构顺序: 【例3-5】:构造函数、析构函数的调用顺序
【例3-1】:析构函数例子(Person类)
摘选内容: class Person { private: … public: ~Person( ); //析构函数 … }; Person::~Person( ) //析构函数的类外定义 { age=90; cout<<"我,我,已经不行了,"; cout<<"把我的遗体捐献给医院,......"<<endl<<endl; }
第10讲 构造函数与析构函数
什么是构造函数 带参数的构造函数 重载构造函数 什么是析构函数 构造函数与析构函数的调用顺序
1. 什么是构造函数(constructor) (1)为什么要有构造函数?(即构造函数的作用)
现在,回顾一下上一讲的相关内容:对象的创 建、使用过程
类的声明 例如: class Date {….}; //类的实现 ……
(2)析构函数的性质 析构函数是一种特殊的成员函数,除具有一般成 员函数的特性外,还具有如下特性:
析构函数的函数名必须与其类名相同,不能指定返回类型, 也不能使用void。为了能与构造函数相区别,要在函数名 前加~(波浪符); 析构函数没有参数,一个类中只能拥有一个析构函数,所以 析构函数不能重载。定义格式为: ~类名( ){ 函数体 } ; 如果程序员没有定义类的析构函数,系统会自动为类创建一 个默认析构函数,形式为: ~类名( ){ }; 通常为public类型,系统在撤消对象时,自动调用析构函数。 也允许显式调用。
下面,我们通过程序来模拟人的一生进一步来 说明构造函数、析构函数作用
哇! 我出生了... 我叫贝贝,我是一个快乐的小女孩! 我已经3岁,正在上幼儿园... (人生历程) 我已经22岁,开始工作了... 显式调用 公用函数 我已满55岁,已经退休了... 完成 我,我,已经不行了,把我的遗体捐献给医院,...... (出生宣言) 自动调用构 造函数完成
2. 带参数的构造函数
(1)用不同的参数去调用构造函数,以实现不同对象 的初始化,体现对象的多样性。 构造函数首部的一般格式: 构造函数名(类型1 形参1,类型2 形参2,…); 定义对象的一般格式: 类名 对象名(实参1,实参2,… );
class Date { public: Date(int y, int m, int d) //定义带参数的构造函数 { year=y, month=m, day=d; } … }; //定义对象 Date today(2008,9,16), tomorrow(2008,9,17);
程序运行结果: 现在再声明Student类: Date类构造函数被调用! class Student { private: Student类构造函数被调用! int ID; 学号: 123456 Date birthday; //用Date类的对象作数据成员 出生日期: 1980年12月3日 public: Student(int s_id,int s_by, int s_bm, int s_bd):ID(s_id),birthday(s_by,s_bm,s_bd) { cout<<"Student类构造函数被调用!"<<endl; } //构造函数 …… }; … //代码见课件中”【例3-2】:类成员初始化.doc”
【例3-4】:构造函数、析构函数例子(动态分配、释放内存)
回收
//student.cpp 栈区 堆区 … CStudent::CStudent() { z pName … h pName=new char[20]; //动态分配内存 析构时,pName 指针会丢弃 a strcpy(pName, "zhangsan"); 掉,通过 delete 释放其在堆 里分配的内存 … …; } n CStudent::~CStudent() //定义析构函数 \0 { if(pName) //在析构函数里检查是否为pName成功分配了内存 { delete []pName; //释放pName所指向的内存。 } } …