在 C++ 中,子类(派生类)继承父类(基类) 是面向对象编程(OOP)的核心概念之一,允许子类复用父类的成员变量和成员函数,并可以扩展或修改其行为。
1. 基本语法
继承方式
C++ 支持三种继承方式:
-
public(公有继承):父类的public和protected成员在子类中保持原有访问权限。 -
protected(保护继承):父类的public和protected成员在子类中变为protected。 -
private(私有继承,默认):父类的public和protected成员在子类中变为private。
cpp
class Base {
public:
int publicVar;
protected:
int protectedVar;
private:
int privateVar; // 子类无法直接访问
};
// 公有继承(最常用)
class DerivedPublic : public Base {
// publicVar 仍然是 public
// protectedVar 仍然是 protected
// privateVar 不可访问
};
// 保护继承
class DerivedProtected : protected Base {
// publicVar 变为 protected
// protectedVar 仍然是 protected
// privateVar 不可访问
};
// 私有继承
class DerivedPrivate : private Base {
// publicVar 变为 private
// protectedVar 变为 private
// privateVar 不可访问
};
2. 子类访问父类成员
-
public继承:-
子类可以访问父类的
public和protected成员。 -
外部代码只能访问子类的
public成员(包括继承自父类的public成员)。
-
-
protected/private继承:-
父类的
public成员在子类中降级为protected或private,外部无法直接访问。
-
cpp
class Base {
public:
void publicFunc() { cout << "Base::publicFunc" << endl; }
protected:
void protectedFunc() { cout << "Base::protectedFunc" << endl; }
private:
void privateFunc() { cout << "Base::privateFunc" << endl; }
};
class Derived : public Base {
public:
void callBaseMethods() {
publicFunc(); // ✅ 可以访问
protectedFunc(); // ✅ 可以访问
// privateFunc(); // ❌ 编译错误,无法访问
}
};
int main() {
Derived d;
d.publicFunc(); // ✅ 可以访问(因为是 public 继承)
// d.protectedFunc(); // ❌ 编译错误,外部不能访问 protected
d.callBaseMethods(); // ✅ 调用子类方法
return 0;
}
3. 构造函数和析构函数
-
构造函数:
-
子类构造时,先调用父类构造函数,再调用子类构造函数。
-
如果父类没有默认构造函数,必须在子类构造函数初始化列表中显式调用父类构造函数。
-
-
析构函数:
-
子类析构时,先调用子类析构函数,再调用父类析构函数(栈式销毁)。
-
cpp
class Base {
public:
Base() { cout << "Base Constructor" << endl; }
Base(int x) { cout << "Base(int)" << endl; }
~Base() { cout << "Base Destructor" << endl; }
};
class Derived : public Base {
public:
Derived() : Base(42) { // 显式调用父类构造函数
cout << "Derived Constructor" << endl;
}
~Derived() {
cout << "Derived Destructor" << endl;
}
};
int main() {
Derived d;
return 0;
}
输出:
text
Base(int) Derived Constructor Derived Destructor Base Destructor
4. 函数重写(Override)
-
如果子类定义了与父类 同名、同参数、同返回类型 的成员函数,则子类会 覆盖(override) 父类方法。
-
如果希望明确表示覆盖,可以使用
override关键字(C++11 起)。 -
如果希望调用父类方法,可以使用
Base::method()。
cpp
class Base {
public:
virtual void show() { // virtual 允许子类覆盖
cout << "Base::show" << endl;
}
};
class Derived : public Base {
public:
void show() override { // 明确表示覆盖
cout << "Derived::show" << endl;
}
void callBaseShow() {
Base::show(); // 显式调用父类方法
}
};
int main() {
Derived d;
d.show(); // 输出 "Derived::show"
d.callBaseShow(); // 输出 "Base::show"
return 0;
}
5. 多重继承(Multiple Inheritance)
C++ 允许一个子类继承多个父类(但容易导致 菱形继承问题,需谨慎使用)。
cpp
class A {
public:
void funcA() { cout << "A::funcA" << endl; }
};
class B {
public:
void funcB() { cout << "B::funcB" << endl; }
};
class C : public A, public B {
public:
void funcC() {
funcA(); // 调用 A 的方法
funcB(); // 调用 B 的方法
}
};
int main() {
C c;
c.funcA();
c.funcB();
c.funcC();
return 0;
}
6. 虚继承(解决菱形继承问题)
如果多个父类继承同一个基类,可能导致 数据冗余和二义性,可以用 virtual 继承解决。
cpp
class GrandParent {
public:
int data;
};
class Parent1 : virtual public GrandParent {}; // 虚继承
class Parent2 : virtual public GrandParent {}; // 虚继承
class Child : public Parent1, public Parent2 {
public:
void setData(int x) {
data = x; // 现在不会二义性,因为 GrandParent 只存在一份
}
};
int main() {
Child c;
c.setData(42);
return 0;
}
总结
| 特性 | 说明 |
|---|---|
| 继承方式 | public(最常用)、protected、private |
| 访问权限 | 子类可访问父类 public 和 protected,但不能访问 private |
| 构造/析构顺序 | 先父类构造 → 子类构造;先子类析构 → 父类析构 |
| 函数重写 | 使用 override 明确覆盖,Base::method() 调用父类方法 |
| 多重继承 | 允许,但可能导致菱形继承问题 |
| 虚继承 | 解决多重继承的数据冗余和二义性问题 |
掌握这些概念后,可以更灵活地使用 C++ 继承机制设计类层次结构。
2824

被折叠的 条评论
为什么被折叠?



