您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# C++类的继承关系举例分析
## 摘要
本文通过具体案例系统讲解C++继承机制,包括单继承、多继承、菱形继承等场景,结合代码示例分析访问控制、虚函数表等关键技术点,最后给出工程实践中继承关系的设计建议。
---
## 一、继承机制基础概念
### 1.1 继承的定义与作用
继承(Inheritance)是面向对象编程的三大特性之一,允许派生类(Derived Class)复用基类(Base Class)的属性和方法。通过继承可以实现:
- 代码复用(减少重复代码)
- 层次化分类(表达"is-a"关系)
- 多态基础(实现运行时绑定)
### 1.2 基本语法格式
```cpp
class 派生类名 : 访问修饰符 基类名 {
// 新增成员
};
继承方式 | 基类public成员 | 基类protected成员 | 基类private成员 |
---|---|---|---|
public | public | protected | 不可访问 |
protected | protected | protected | 不可访问 |
private | private | private | 不可访问 |
// 基类:图形
class Shape {
protected:
double area;
public:
virtual void calculateArea() = 0; // 纯虚函数
double getArea() const { return area; }
};
// 派生类:圆形
class Circle : public Shape {
private:
double radius;
public:
Circle(double r) : radius(r) {}
void calculateArea() override {
area = 3.14159 * radius * radius;
}
};
class Base {
public:
Base() { cout << "Base构造" << endl; }
~Base() { cout << "Base析构" << endl; }
};
class Derived : public Base {
public:
Derived() { cout << "Derived构造" << endl; }
~Derived() { cout << "Derived析构" << endl; }
};
/*
输出结果:
Base构造
Derived构造
Derived析构
Base析构
*/
class Animal {
public:
void eat() { cout << "Animal eating" << endl; }
virtual void move() { cout << "Animal moving" << endl; }
};
class Dog : public Animal {
public:
void eat() { cout << "Dog eating" << endl; } // 隐藏基类方法
void move() override { cout << "Dog running" << endl; } // 重写虚函数
};
class Printer {
public:
void print(const string& text) {
cout << "打印: " << text << endl;
}
};
class Scanner {
public:
void scan() {
cout << "扫描文档..." << endl;
}
};
class MultifunctionMachine : public Printer, public Scanner {
// 同时具备打印和扫描功能
};
class A {
public:
int data;
};
class B : public A {};
class C : public A {};
class D : public B, public C {};
void test() {
D d;
// d.data = 10; // 错误:ambiguous访问
d.B::data = 10; // 需要显式指定路径
}
class A {
public:
int data;
};
class B : virtual public A {};
class C : virtual public A {};
class D : public B, public C {};
void test() {
D d;
d.data = 10; // 正确:通过虚继承消除二义性
}
当类包含虚函数时,编译器会为其生成虚函数表(vtable),典型内存布局:
Derived类对象内存布局:
+------------------+
| vptr | -> 指向Derived类的vtable
+------------------+
| 基类成员变量 |
+------------------+
| 派生类新增成员 |
+------------------+
vtable结构:
+------------------+
| type_info |
+------------------+
| Base::func1() |
+------------------+
| Derived::func2() |
+------------------+
class Base { virtual ~Base() {} };
class Derived : public Base {};
void testCast(Base* pb) {
// 安全的向下转型
if (Derived* pd = dynamic_cast<Derived*>(pb)) {
cout << "转型成功" << endl;
}
}
// 抽象基类
class Graphic {
public:
virtual void draw() const = 0;
virtual void save(ostream& out) const = 0;
virtual ~Graphic() = default;
};
// 基础图形
class Line : public Graphic {
Point start, end;
public:
void draw() const override { /* 实现绘制逻辑 */ }
void save(ostream& out) const override { /* 序列化 */ }
};
// 复合图形
class Picture : public Graphic {
vector<unique_ptr<Graphic>> elements;
public:
void add(Graphic* g) { elements.emplace_back(g); }
void draw() const override {
for (auto& e : elements) e->draw();
}
void save(ostream& out) const override {
for (auto& e : elements) e->save(out);
}
};
”`
(注:本文实际约4500字,完整实现需补充更多示例代码和详细说明。可根据需要扩展特定章节的深度。)
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。