- 1、本文档共50页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
第5章 构造和析构函数 构造函数和析构函数的引入 带参构造函数和默认构造函数 成员初始化列表 拷贝构造函数 对象的构造顺序 再看new和delete 5.1 构造函数-背景 与结构和其他基本数据类型的变量一样: 定义一个全局对象会将其所占内存空间清0 定义一个局部对象时,不会执行任何初始化动作,其数据成员的值完全依赖于堆栈上的情况。 对象应该表达了现实世界中的相应实体,一旦建立对象,其每个数据成员理应有合理的初始值。 5.1 构造函数-背景 C语言使用下面的语法初始化结构变量: Rectangle r = { 10, 20.0 }; C++中不能使用这种方法,因为某些数据成员可能不是公有成员。 // 错误:不能在类的作用 // 域外访问非公有数据成员 Student stu= { “aa”, 10, 90 }; 为了避免破坏类的封装性,使用特殊的成员函数来负责对象初始化。 5.1 构造函数-要点 与类同名的成员函数称为构造函数(Constructor, ctor),此函数在该类的对象被创建时会被自动调用,负责完成该对象的初始化工作。 构造函数不能指定返回类型。 每定义一个对象,该对象的ctor被自动调用。 Student s; 此句背后的动作是首先为对象s分配内存,然后调用ctor初始化对象。 5.1 构造函数-要点 构造函数不能定义为const的,但是可以用来构造常量对象,这是因为只有当构造函数执行完毕后,对象的常量性才能够建立起来。 Rectangle::Rectangle() const {} // 错误的ctor定义 对于常量对象只能调用常成员函数的规则,构造函数是个例外。 如果一个类对象item是另一个类Container的数据成员,则创建Container的对象时,会首先自动为item调用构造函数。换句话说,编译器会自动在Container的构造函数的函数体前插入对item构造函数的调用。 首先调用对象成员的ctor,其次才是自身的ctor。 [演示] 理解构造函数的调用时机 5.2 析构函数-背景 一个对象的生存期结束(销毁)时可能需要做些清理工作。 打开的文件需要关闭 分配的堆内存需要释放 如果清理工作对应的函数能够被自动调用,就会减少程序员的工作量,甚至出错的可能。 可以使用析构函数(Destructor, dtor)自动完成清理工作。 5.2 析构函数-要点 析构函数名必须为~加上类名。示例 dtor是一类特殊的成员函数,它没有参数,不能重载,不能为其指定返回值。 类中至多只有一个dtor。 dtor在对象的生存期即将结束时由系统自动调用。析构函数返回后,对象结束其生存期。 如果没有清理工作要做,则可以不在类中定义析构函数。 【示例】析构函数 5.2 析构函数-要点 dtor不能定义为常成员函数,但是常量对象在析构的时候同样会调用dtor。 Rectangle::~Rectangle() const {} // 错误的dtor定义 对于常量对象只能调用常成员函数的规则,dtor是个例外。 如果类中包含成员对象,在执行析构函数时将首先执行dtor的函数体,然后为类中的每个对象成员调用析构函数。换句话说,编译器会在类的dtor函数体之后插入对类中每个成员对象的dtor的调用。对dtor的调用顺序正好和对ctor的调用顺序相反。最先构造的对象最后被析构。 [演示] 理解析构函数的调用时机 class Person { public: Person() { m_strName = new char[20]; } // 分配堆空间 ~Person() { delete[] m_strName; } // 释放堆空间 void SetName(const char* name) { strcpy(m_strName, name); } private: char* m_strName; } 5.3 构造函数重载 与dtor不同,ctor允许带参而且可以带不同的参数,ctor允许重载。 教材P273页的例子 MFC中的CString的类定义 在一个构造函数中调用重载的另一个构造函数以简化编程的方法是错误的。因为构造函数只用于创建对象。这一点和普通重载函数不同。 class Tdate { public: Tdate(int m = 4, d = 22, y = 2005); private: int month; int day; int year; }; Tdate::Tdate(int m /* = 4 */, int d /* = 22 */,int y /* = 2005 */) { mont
文档评论(0)