📅  最后修改于: 2023-12-03 15:29:42.656000             🧑  作者: Mango
继承是面向对象编程中一个重要的概念,可以让子类继承父类的属性和方法,从而提高代码复用性并简化开发过程。在 C++ 中,继承有多种类型,并且存在一些特殊的情况需要特别注意。
C++ 中使用 class
或 struct
定义派生类时,通常需要继承一个或多个基类。继承语法如下所示:
class ChildClass : public ParentClass {
// ...
};
其中,ChildClass
即为派生类,ParentClass
则为基类。派生类可以在基类提供的成员函数和成员变量基础上增加额外的功能。
在 C++ 中,派生类可以通过不同的继承方式继承基类,包括:
public
关键字表示,派生类继承了基类的所有公有成员;protected
关键字表示,派生类继承了基类的所有公有和保护成员;private
关键字表示,派生类继承了基类的所有公有、保护和私有成员,但是基类的所有成员在派生类中均变为私有成员。在派生类中,可以通过基类名限定符的方式访问基类中的成员。例如,假设 ChildClass
继承自 ParentClass
,则可以通过以下方式访问基类中的公有成员 parentMember
:
class ChildClass : public ParentClass {
public:
void childMethod() {
parentMember = 10; // 直接访问基类成员
ParentClass::parentMember = 20; // 使用限定符访问基类成员
}
};
在多重继承的情况下,如果派生类同时从两个或更多个基类中继承了相同的成员,则可能会导致二义性问题。例如,假设 ChildClass
同时从 ClassA
和 ClassB
中继承了一个名为 member
的成员:
class ClassA {
public:
int member;
};
class ClassB {
public:
int member;
};
class ChildClass : public ClassA, public ClassB {
public:
void childMethod() {
//member = ?; // 二义性问题:无法确定访问哪个基类的成员
}
};
在这种情况下,访问 member
成员时将会出现二义性问题,需要使用基类名限定符来解决。
菱形继承指的是多重继承中的一种情况,其中有一个类同时继承自两个以上的类,在这些类中又有一个共同的基类,如下图所示:
在这种情况下,派生类将会继承两个相同基类的实例,可能会导致内存浪费和二义性问题。例如,假设 LeafClass
继承自 ParentB
和 ParentC
,而这两个类又都继承自 ParentA
:
class ParentA {
public:
int memberA;
};
class ParentB : public ParentA {
public:
int memberB;
};
class ParentC : public ParentA {
public:
int memberC;
};
class LeafClass : public ParentB, public ParentC {
public:
void leafMethod() {
ParentB::memberA = 10; // 正确,指定了访问哪个基类的成员
//memberA = ?; // 二义性问题:无法确定访问哪个基类的成员
}
};
在这种情况下,访问 memberA
成员时也会出现二义性问题,需要使用基类名限定符来指定访问哪个基类的成员。
虚继承是为了解决菱形继承问题而引入的一种继承方式,可以让派生类共享基类的实例。虚继承使用 virtual
关键字表示,派生类继承的是基类的虚基类而不是直接继承自基类。例如,通过将 ParentA
改为虚基类,可以解决上述菱形继承的问题:
class ParentA {
public:
int memberA;
};
class ParentB : virtual public ParentA {
public:
int memberB;
};
class ParentC : virtual public ParentA {
public:
int memberC;
};
class LeafClass : public ParentB, public ParentC {
public:
void leafMethod() {
memberA = 10; // 正确:共享基类实例
}
};
在这种情况下,派生类 LeafClass
将会共享基类 ParentA
的实例,可以避免内存浪费和二义性问题。
继承是 C++ 中一种重要的概念,可以让派生类继承基类的属性和方法,从而提高代码复用性。在使用继承时,需要注意多重继承和菱形继承可能会导致二义性和内存浪费问题,可以通过基类名限定符和虚继承来解决这些问题。