子类的构造,析构和拷贝
2017-08-07 11:25
134 查看
子类的构造函数
一.隐式构造基类•如果子类的构造函数没有显式指明其基类部分的构造方式,那么编译器会选择其基类的缺省构造函数,构造该子类对象中的基类子对象
–class Student : public Human { public: Student (int no) : m_no (no) {} };
•但是请注意,只有在为基类显式提供一个无参构造函数,或者不提供任何构造函数(系统会提供一个缺省的无参构造函数)的情况下,基类才拥有无参构造函数
二.显式构造基类
•子类的构造函数可以在初始化表中显式指明其基类部分的构造方式,即通过其基类的特定构造函数,构造该子类对象中的基类子对象
–class Human { public: Human (string const& name, int age) : m_name (name), m_age (age) {} };
–class Student : public Human { public: Student (string const& name, int age, int no) : Human (name, age), m_no (no) {} };
三.子类对象的构造过程
•子类的构造函数执行如下步骤:
–首先,按照继承表的顺序,依次调用各个基类的构造函数,构造子类对象中的基类子对象
–其次,按照声明的顺序,依次调用各个类类型成员变量相应类型的构造函数,构造子类对象中的成员子对象
–最后,执行子类构造函数体中的代码,完成整个构造过程
•无论如何,子类的构造函数都一定会(显式或隐式地)调用其基类和类类型成员变量类型的构造函数
子类的析构函数
一.子类负责析构基类•子类的析构函数,无论是自己定义的(自定义析构函数)还是系统提供的(缺省析构函数),在执行完其中的析构代码,
并析构完所有的类类型成员子对象以后,会自动调用其基类的析构函数,析构该子类对象中的基类子对象
–class Human { ... }; –class Student : public Human { public: ~Student (void) { ... /* ~Human () */ } }; –Student* student = new Student (...); delete student;
二.基类不会析构子类
•对一个指向子类对象的基类指针使用delete运算符,实际被调用的将是基类的析构函数,该函数不会调用子类的析构函数,
其所析构的仅仅是子类对象中的基类子对象,而子类的扩展部分极有可能因此而形成内存泄漏
–class Human { public: ~Human (void) { ... } }; –class Student : public Human { ... }; –Human* human = new Student (...); delete human;
三.子类对象的析构过程
•子类的析构函数执行如下步骤:
–首先,执行子类析构函数体中的代码,析构子类的扩展部分
–其次,按照声明的逆序,依次调用各个类类型成员变量相应类型的析构函数,析构子类对象中的成员子对象
–最后,按照继承表的逆序,依次调用各个基类的析构函数,析构子类对象中的基类子对象,完成整个析构过程
•无论如何,子类的析构函数都一定会隐式地调用其类类型成员变量类型和基类的析构函数
子类的拷贝构造
一.缺省全拷贝•如果子类没有定义拷贝构造函数,那么编译器为子类提供的缺省拷贝构造函数,会自动调用其基类的(自定义或缺省)拷贝构造函数,拷贝构造子类对象中的基类子对象
–class Student : public Human { public: Student (String const& name, int age, int no) : Human (name, age), m_no (no) {} /* Student (Student const& that) : Human (that) { ... } */ };
二.自定义局部拷贝
•如果子类定义了拷贝构造函数,但没有显式指明以拷贝方式构造其基类部分,那么编译器会选择其基类的缺省构造函数,构造子类对象中的基类子对象
–class Student : public Human { public: Student (String const& name, int age, int no) : Human (name, age), m_no (no){} Student (Student const& that) : /* Human (), */ m_no (that.m_no) {} };
三.自定义全拷贝
•如果子类定义了拷贝构造函数,同时显式指明了其基类部分以拷贝方式构造,那么子类对象中的基类部分和扩展部分将一起被复制
–class Student : public Human { public: Student (String const& name, int age, int no) : Human (name, age), m_no (no) {} Student (Student const& that) : Human (that), m_no (that.m_no) {} };
子类的拷贝赋值
一.缺省全赋值•如果子类没有定义拷贝赋值运算符函数,那么编译器为子类提供的缺省拷贝赋值运算符函数,会自动调用其基类的(自定义或缺省)拷贝赋值运算符函数,复制子类对象中的基类子对象
–class Student : public Human { /* Student& operator= (Student const& rhs) { ... Human::operator= (rhs) ... } */ };
二.自定义局部赋值
•如果子类定义了拷贝赋值运算符函数,但没有显式调用其基类的拷贝赋值运算符函数,那么子类对象中的基类子对象将因得不到复制而保持原状
–class Student : public Human { public: Student& operator= (Student const& rhs) { if (&rhs != this) m_no = rhs.m_no; return *this; } };
三.自定义全赋值
•如果子类定义了拷贝赋值运算符函数,同时显式调用了其基类的拷贝赋值运算符函数,那么子类对象中的基类部分和扩展部分将一起被复制
–class Student : public Human { public: Student& operator= (Student const& rhs) { if (&rhs != this) { Human::operator= (rhs); m_no = rhs.m_no; } return *this; } };
相关文章推荐
- 【深度探索C++对象模型读书笔记】【第5章】构造、析构、拷贝语意学
- C++【子类的构造和析构】
- 类的基本成员函数实现(构造,拷贝构造,拷贝赋值,移动构造,移动赋值,析构)
- c++子类对象构造与析构的顺序对多态性的影响
- 【深度探索C++对象模型读书笔记】【第5章】构造、析构、拷贝语意学
- 构造、拷贝(复制)构造、赋值构造以及析构
- [读书笔记] 深入探索C++对象模型-第五章-构造、析构、拷贝语义学(下)
- C++对象模型 ch5 构造 析构 拷贝语义学
- C++ 了解C++默默编写并调用哪些函数(构造 析构 拷贝构造 拷贝赋值)
- 继承中构造、析构 与 拷贝构造、赋值中的调用区别
- C++编程规范(六) 构造、析构和拷贝
- 结构体的构造、拷贝、赋值、析构和字符串的拷贝、构造、赋值和析构函数的比较
- 手写两个类,要体现构造,析构,拷贝构造,赋值,虚函数,重载函数等特点。
- 深度探索C++对象模型(五)构造、析构、拷贝语意学
- C++对象模型 第五章 构造、析构、拷贝语意学
- 类中嵌套另一个类时,调用构造,析构,拷贝,赋值运算符等函数的次序
- string的四个函数--构造、析构、拷贝、赋值
- object构造、拷贝构造、析构、临时对象
- C++对象的构造与拷贝以及析构
- 类构造,析构,赋值,拷贝