C++ 中的类继承是面向对象编程的核心特性之一,它允许一个类(派生类)从另一个类(基类)继承属性和行为。通过继承,可以实现代码的重用和扩展。以下是关于 C++ 类继承的详细说明:
1.继承的基本语法
C++ 中使用 : 符号表示继承关系。语法如下:
class BaseClass {
// 基类成员
};
class DerivedClass : access-specifier BaseClass {
// 派生类成员
};
- access-specifier: 访问修饰符,可以是 public、protected 或 private。
- public: 基类的 public 成员在派生类中仍然是 public,protected 成员仍然是 protected。
- protected: 基类的 public 和 protected 成员在派生类中变为 protected。
- private: 基类的 public 和 protected 成员在派生类中变为 private。
2.继承的类型
C++ 支持三种继承方式:
(1)公有继承 (public)
- 基类的 public 成员在派生类中仍然是 public。
- 基类的 protected 成员在派生类中仍然是 protected。
- 基类的 private 成员在派生类中不可访问。
class Base {
public:
int publicVar;
protected:
int protectedVar;
private:
int privateVar;
};
class Derived : public Base {
// publicVar 是 public
// protectedVar 是 protected
// privateVar 不可访问
};
(2)保护继承 (protected)
- 基类的 public 和 protected 成员在派生类中变为 protected。
- 基类的 private 成员在派生类中不可访问。
class Derived : protected Base {
// publicVar 是 protected
// protectedVar 是 protected
// privateVar 不可访问
};
(3)私有继承 (private)
- 基类的 public 和 protected 成员在派生类中变为 private。
- 基类的 private 成员在派生类中不可访问。
class Derived : private Base {
// publicVar 是 private
// protectedVar 是 private
// privateVar 不可访问
};
3.构造函数和析构函数的调用顺序
- 构造函数调用顺序:
- 基类的构造函数。
- 派生类的构造函数。
- 析构函数调用顺序:
- 派生类的析构函数。
- 基类的析构函数。
class Base {
public:
Base() { std::cout << "Base Constructor\n"; }
~Base() { std::cout << "Base Destructor\n"; }
};
class Derived : public Base {
public:
Derived() { std::cout << "Derived Constructor\n"; }
~Derived() { std::cout << "Derived Destructor\n"; }
};
int main() {
Derived obj; // 输出:
// Base Constructor
// Derived Constructor
// Derived Destructor
// Base Destructor
return 0;
}
4.函数重写(Override)
- 派生类可以重写基类的虚函数(virtual)。
- 使用 override 关键字明确表示重写(C++11 引入)。
class Base {
public:
virtual void show() {
std::cout << "Base show\n";
}
};
class Derived : public Base {
public:
void show() override { // 重写基类的 show 函数
std::cout << derived show\n int main base obj='new' derived obj->show(); // 输出: Derived show
delete obj;
return 0;
}
5.多重继承
C++ 支持多重继承,即一个派生类可以从多个基类继承。
class Base1 {
public:
void func1() { std::cout << "Base1 func1\n"; }
};
class Base2 {
public:
void func2() { std::cout << "Base2 func2\n"; }
};
class Derived : public Base1, public Base2 {
public:
void func3() { std::cout << "Derived func3\n"; }
};
int main() {
Derived obj;
obj.func1(); // 输出: Base1 func1
obj.func2(); // 输出: Base2 func2
obj.func3(); // 输出: Derived func3
return 0;
}
6.虚继承
- 用于解决多重继承中的菱形继承问题(即一个类通过多条路径继承同一个基类)。
- 使用 virtual 关键字实现虚继承。
class Base {
public:
int data;
};
class Derived1 : virtual public Base {};
class Derived2 : virtual public Base {};
class FinalDerived : public Derived1, public Derived2 {};
int main() {
FinalDerived obj;
obj.data = 10; // 不会产生二义性
return 0;
}
7.访问控制
- public 成员: 可以在类外部访问。
- protected 成员: 只能在派生类和类内部访问。
- private 成员: 只能在类内部访问。
class Base {
public:
int publicVar;
protected:
int protectedVar;
private:
int privateVar;
};
class Derived : public Base {
public:
void accessBase() {
publicVar = 1; // 可以访问
protectedVar = 2; // 可以访问
// privateVar = 3; // 错误:不可访问
}
};
int main() {
Derived obj;
obj.publicVar = 10; // 可以访问
// obj.protectedVar = 20; // 错误:不可访问
// obj.privateVar = 30; // 错误:不可访问
return 0;
}
8.总结
- C++ 的类继承支持单继承、多重继承和虚继承。
- 通过继承可以实现代码重用和扩展。
- 访问修饰符(public、protected、private)控制基类成员在派生类中的可见性。
- 构造函数和析构函数的调用顺序是基类先于派生类。
- 函数重写和虚函数是实现多态的关键。