非抽象类继承和虚函数
cpp
#include <iostream>
using namespace std;
class Base {
public:
virtual void func() { // 虚函数,支持动态绑定
cout << "Base::func()" << endl;
}
};
class Derived : public Base {
public:
void func() override { // 重写虚函数
cout << "Derived::func()" << endl;
}
};
void call_by_pointer(Base* ptr) {
ptr->func(); // 动态多态:通过基类指针调用虚函数,实际调用派生类函数
}
void call_by_reference(Base& ref) {
ref.func(); // 动态多态:通过基类引用调用虚函数,实际调用派生类函数
}
int main() {
Derived d_obj;
Base b_obj;
cout << "--- 1. 通过对象直接调用 ---" << endl;
d_obj.func(); // 非动态多态:对象类型是 Derived,编译期已决定调用 Derived::func()
b_obj.func(); // 非动态多态:对象类型是 Base,编译期决定调用 Base::func()
cout << "--- 2. 通过基类指针指向派生类对象 ---" << endl;
Base* b_ptr = &d_obj;
b_ptr->func(); // 动态多态:基类指针指向派生类对象,调用 Derived::func()
cout << "--- 3. 通过基类引用指向派生类对象 ---" << endl;
Base& b_ref = d_obj;
b_ref.func(); // 动态多态:基类引用指向派生类对象,调用 Derived::func()
cout << "--- 4. 通过函数传参:指针方式 ---" << endl;
call_by_pointer(&d_obj); // 动态多态
cout << "--- 5. 通过函数传参:引用方式 ---" << endl;
call_by_reference(d_obj); // 动态多态
cout << "--- 6. new 派生类对象赋值给基类指针 ---" << endl;
Base* heap_ptr = new Derived();
heap_ptr->func(); // 动态多态
delete heap_ptr;
cout << "--- 7. 对象切片(slicing) ---" << endl;
Base sliced = d_obj; // 非动态多态:对象切片,Derived 部分被切掉
sliced.func(); // 调用的是 Base::func()
cout << "--- 8. 基类对象指向派生类地址(强转) ---" << endl;
Base* forced_ptr = (Base*)&d_obj;
forced_ptr->func(); // 动态多态:虽然是强转,但对象真实类型仍是 Derived
return 0;
}
抽象基类 + 纯虚函数(接口模式)
cpp
#include <iostream>
#include <vector>
#include <memory>
using namespace std;
// 抽象基类 Shape,定义接口
class Shape {
public:
virtual double area() const = 0; // 纯虚函数
virtual ~Shape() = default; // 虚析构,保证多态删除安全
};
class Circle : public Shape {
double radius;
public:
Circle(double r) : radius(r) {}
double area() const override { return 3.14159 * radius * radius; }
};
class Rectangle : public Shape {
double w, h;
public:
Rectangle(double w_, double h_) : w(w_), h(h_) {}
double area() const override { return w * h; }
};
void printArea(const Shape& s) {
// ✅ 动态多态:通过基类引用调用纯虚函数
cout << "Area = " << s.area() << endl;
}
int main() {
vector<unique_ptr<Shape>> shapes;
shapes.emplace_back(make_unique<Circle>(2.0));
shapes.emplace_back(make_unique<Rectangle>(3.0, 4.0));
for (auto& shp : shapes) {
printArea(*shp);
}
return 0;
}
// 场景:用纯虚函数定义接口,派生类实现具体算法。
// 动态多态点:printArea(*shp) 内部的 s.area()
返回类型
cpp
#include <iostream>
using namespace std;
// 原型接口
class Prototype {
public:
virtual Prototype* clone() const = 0; // 纯虚
virtual void show() const = 0;
virtual ~Prototype() = default;
};
class ConcreteA : public Prototype {
int data;
public:
ConcreteA(int d) : data(d) {}
// 协变返回:派生类返回自身类型指针
ConcreteA* clone() const override {
return new ConcreteA(*this);
}
void show() const { cout << "ConcreteA: " << data << endl; }
};
int main() {
Prototype* p1 = new ConcreteA(42);
Prototype* p2 = p1->clone(); // 动态多态:clone() 调用派生实现
p2->show();
delete p1;
delete p2;
return 0;
}
// 场景:通过原型克隆对象,每个具体类返回其自身类型指针。
// 动态多态点:p1->clone()。
多接口继承抽象类
cpp
#include <iostream>
using namespace std;
class Printable {
public:
virtual void print() const = 0;
virtual ~Printable() = default;
};
class Drawable {
public:
virtual void draw() const = 0;
virtual ~Drawable() = default;
};
class Widget : public Printable, public Drawable {
public:
void print() const override { cout << "Widget::print()\n"; }
void draw() const override { cout << "Widget::draw()\n"; }
};
int main() {
Widget w;
Printable* p = &w;
Drawable* d = &w;
p->print(); // 动态多态:调用 Widget::print()
d->draw(); // 动态多态:调用 Widget::draw()
return 0;
}
// 场景:组件同时具备"可打印"和"可绘制"能力,用两个接口分离职责。
// 动态多态点:通过不同基类指针调用对应虚函数。
运行时类型识别(RTTI)+ dynamic_cast
cpp
#include <iostream>
using namespace std;
class Base {
public:
virtual ~Base() = default;
};
class Derived : public Base {
public:
void special() { cout << "Derived::special()\n"; }
};
void trySpecial(Base* b) {
// 动态多态 & RTTI:运行时检查实际类型
if (auto* d = dynamic_cast<Derived*>(b)) {
d->special();
} else {
cout << "Not a Derived\n";
}
}
int main() {
Base* b1 = new Base;
Base* b2 = new Derived;
trySpecial(b1); // 输出 "Not a Derived"
trySpecial(b2); // 输出 "Derived::special()"
delete b1;
delete b2;
return 0;
}
// 场景:当你只持有基类指针,但有时需要访问派生类的独有方法。
// 动态多态点:dynamic_cast 根据实际类型成功或失败。
插件式架构(Factory + 多态)
cpp
#include <iostream>
#include <string>
#include <map>
#include <functional>
using namespace std;
class Plugin {
public:
virtual void run() = 0;
virtual ~Plugin() = default;
};
class PluginA : public Plugin {
public:
void run() override { cout << "PluginA running\n"; }
};
class PluginB : public Plugin {
public:
void run() override { cout << "PluginB running\n"; }
};
// 简单工厂注册表
map<string, function<Plugin*()>> factoryMap;
void registerPlugin(const string& name, function<Plugin*()> ctor) {
factoryMap[name] = ctor;
}
Plugin* createPlugin(const string& name) {
auto it = factoryMap.find(name);
return it != factoryMap.end() ? it->second() : nullptr;
}
int main() {
// 注册
registerPlugin("A", [](){ return new PluginA; });
registerPlugin("B", [](){ return new PluginB; });
// 客户端只知道名字,工厂返回多态基类
Plugin* p = createPlugin("A");
if (p) p->run(); // ? 动态多态:调用 PluginB::run()
delete p;
return 0;
}
// 场景:插件或驱动加载,客户端通过字符串、配置决定用哪个实现。
// 动态多态点:p->run()。