C++(三十八) — 继承方式、访问控制、构造和析构、虚继承
派生类继承了基类的所有成员,但不包含 构造函数、析构函数、默认赋值运算符。
1、继承方式、访问控制
(1)protected属性:类的对象不能访问该属性成员,但派生类的成员函数可以访问基类的protected属性成员。
(2)无论哪种继承方式,派生类成员函数都可访问:public、protected ,但不能是基类的 private;
(3)什么属性的继承,在派生类中就是什么属性。
C++中的继承方式会影响子类的对外访问属性,判断原则如下:
(a)看调用语句,写在子类的内部还是外部;
(b)看子类如何从父类继承;
(c)看父类中的访问级别;
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include<cstring> using namespace std; class Document { public: Document(); Document(char* name); ~Document() { } void PrintName(); private: char *Name; }; Document::Document(char *name) { Name = new char[strlen(name) + 1]; strcpy(Name, name); } void Document::PrintName() { cout << Name << endl; } class Book : public Document { public: Book(char name[], int pagecout); void PrintName(); private: int PageCount; }; Book::Book(char *name, int pagecount) :Document(name) { PageCount = pagecount; } void Book::PrintName() { cout << "name of book: "; Document::PrintName(); } int main() { Document a("Document1"); a.PrintName(); Book b("Book1", 100); b.PrintName(); system("pause"); return 0; }
2、派生类的构造和析构
(1)基类的构造和析构函数不能被派生类所继承,派生类需要定义自己的。基类具有无参构造函数,派生类未定义自己的,则系统自动调用基类的无参构造来初始化派生类。若基类没有无参的,派生类也不自己定义,则编译会出错。
(2)派生类的析构函数:不能继承基类的,只可以自己定义,且只负责清理它新定义的成员,清理位于堆区的成员。
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include<string> using namespace std; class Cpolygon { private: double side1, side2; public: Cpolygon(double, double); double value_1() { return side1; } double value_2() { return side2; } void get_values() { cout << "side1= " << side1 << "side2= " << side2 << endl; } }; Cpolygon::Cpolygon(double a, double b) { side1 = a; side2 = b; } class Crectangle :public Cpolygon { public: Crectangle(double, double); double area() { return (value_1()*value_2()); } void get_values() { cout << "长方形的边长: "; Cpolygon::get_values(); cout << "面积:" << area() << endl; } }; // 派生类的构造函数 Crectangle::Crectangle(double a, double b):Cpolygon(a,b){} int main() { Crectangle rec(4, 5); rec.get_values(); system("pause"); return 0; }
3、虚继承
派生类中的 static 关键字:类内定义,类外初始化,在初始化的时候分配内存。
1、多继承与二义性
多继承:派生类有多个直接基类或间接基类;
二义性:派生类的多继承引起二义性,基类构造函数调用了两次,也析构了两次;
2、虚继承
解决方法:将共有基类设置为虚基类;
// 虚基类
class Fderiver1 :virtual public base
{
};