当前位置: 首页 > news >正文

C++虚函数与运行时多态

C++虚函数与运行时多态

虚函数通过虚函数表(vtable)和虚函数指针(vptr)实现运行时多态。当通过基类指针或引用调用虚函数时,程序根据对象的实际类型动态分派到正确的函数实现。

虚函数使用virtual关键字声明,派生类使用override关键字明确重写意图。

#include
#include
#include
#include

class Animal {
public:
virtual ~Animal() = default;

virtual void make_sound() const {
std::cout << "Animal makes a generic sound\n";
}

virtual void move() const {
std::cout << "Animal moves\n";
}

void describe() const {
std::cout << "This is an animal\n";
}
};

class Dog : public Animal {
public:
void make_sound() const override {
std::cout << "Dog barks: Woof!\n";
}

void move() const override {
std::cout << "Dog runs on four legs\n";
}
};

class Cat : public Animal {
public:
void make_sound() const override {
std::cout << "Cat meows: Meow!\n";
}

void move() const override {
std::cout << "Cat walks gracefully\n";
}
};

void polymorphism_demo() {
std::vector> animals;
animals.push_back(std::make_unique());
animals.push_back(std::make_unique());

for (const auto& animal : animals) {
animal->make_sound();
animal->move();
std::cout << "---\n";
}
}

纯虚函数定义接口契约,包含纯虚函数的类是抽象类,不能实例化。

class Shape {
public:
virtual ~Shape() = default;
virtual double area() const = 0;
virtual double perimeter() const = 0;
virtual void draw() const = 0;
};

class Circle : public Shape {
double radius_;
public:
explicit Circle(double r) : radius_(r) {}

double area() const override {
return 3.14159265358979 * radius_ * radius_;
}

double perimeter() const override {
return 2.0 * 3.14159265358979 * radius_;
}

void draw() const override {
std::cout << "Circle (radius=" << radius_ << ")\n";
}
};

class Rectangle : public Shape {
double width_, height_;
public:
Rectangle(double w, double h) : width_(w), height_(h) {}

double area() const override { return width_ * height_; }
double perimeter() const override { return 2 * (width_ + height_); }

void draw() const override {
std::cout << "Rectangle (" << width_ << "x" << height_ << ")\n";
}
};

void abstract_class_demo() {
std::vector> shapes;
shapes.push_back(std::make_unique(5.0));
shapes.push_back(std::make_unique(4.0, 6.0));

double total = 0;
for (const auto& s : shapes) {
s->draw();
total += s->area();
std::cout << "Area: " << s->area() << "\n";
}
std::cout << "Total area: " << total << "\n";
}

虚析构函数确保派生类正确析构。

class Base {
public:
Base() { std::cout << "Base constructed\n"; }
virtual ~Base() { std::cout << "Base destroyed\n"; }
};

class Derived : public Base {
int* data_;
public:
Derived() : data_(new int[100]) {
std::cout << "Derived constructed\n";
}
~Derived() override {
delete[] data_;
std::cout << "Derived destroyed\n";
}
};

void virtual_destructor_demo() {
Base* ptr = new Derived();
delete ptr;
}

dynamic_cast进行运行时类型转换。

void dynamic_cast_demo() {
std::vector> animals;
animals.push_back(std::make_unique());
animals.push_back(std::make_unique());

for (auto& animal : animals) {
if (Dog* dog = dynamic_cast(animal.get())) {
std::cout << "Found a dog\n";
} else if (Cat* cat = dynamic_cast(animal.get())) {
std::cout << "Found a cat\n";
}
}
}

typeid获取运行时类型信息。

void typeid_demo() {
std::unique_ptr animal = std::make_unique();
std::cout << "Type name: " << typeid(*animal).name() << "\n";
std::cout << "Is Dog: " << (typeid(*animal) == typeid(Dog)) << "\n";
std::cout << "Is Cat: " << (typeid(*animal) == typeid(Cat)) << "\n";
}

final关键字防止继承和重写。

class BaseFinal {
public:
virtual void func() final {
std::cout << "Cannot override\n";
}
};

多重接口继承。

class Printable {
public:
virtual ~Printable() = default;
virtual void print() const = 0;
};

class Serializable {
public:
virtual ~Serializable() = default;
virtual std::string serialize() const = 0;
};

class Document : public Printable, public Serializable {
std::string content_;
public:
explicit Document(const std::string& c) : content_(c) {}

void print() const override {
std::cout << content_ << "\n";
}

std::string serialize() const override {
return "DOC:" + content_;
}
};

void multiple_interface_demo() {
Document doc("Hello World");
doc.print();
std::cout << "Serialized: " << doc.serialize() << "\n";
}

协变返回类型。

class Cloneable {
public:
virtual Cloneable* clone() const { return new Cloneable(*this); }
};

class CloneableDerived : public Cloneable {
public:
CloneableDerived* clone() const override {
return new CloneableDerived(*this);
}
};

虚函数是实现运行时多态的基础,理解vtable机制有助于设计灵活的面向对象系统。

http://www.jsqmd.com/news/1046370/

相关文章:

  • OpenPLC Editor完全指南:3步搞定免费工业自动化编程
  • 2026年口碑好的PE穿线管/PE电力管/安徽PE管/安徽PE电力管推荐厂家精选 - 品牌宣传支持者
  • 深度解析免费OpenAI API密钥架构:技术实现与安全应用指南
  • MC68HC908GZ ESCI模块深度解析:寄存器操作、波特率配置与调试实战
  • 2026年6月目前评价高的水帘除尘器制造厂家选哪家,喷淋塔除尘器/水帘除尘器/湿式除尘器,水帘除尘器批发厂家推荐 - 品牌推荐师
  • 2026衡水本地人必选防水补漏检测维修公司靠谱服务商TOP5推荐:房屋渗漏水检测维修/卫生间/厨房/天花板/阳台/外墙渗漏水检测补漏维修-暗管漏水检测专业仪器精准定位漏水点 - 即刻修防水
  • Mission Planner:新手到专家的无人机地面站完整指南
  • 注意力是你所需要的一切
  • 选择大于努力还是努力大于选择?为什么我们总觉得自己的付出比别人更多,而收获更少?
  • DPDK高性能交换机深度实践:一次RCU延迟释放引发的转发表性能雪崩
  • C++观察者与事件系统
  • 2026菏泽漏水检测维修精选优质服务商TOP5推荐!卫生间漏水/厨房漏水/屋顶天花板漏水/阳台漏水/地下室漏水防水补漏检测维修-正规防水补漏公司优选口碑榜测评推荐 - 即刻修防水
  • 厂家工业专用吸尘器十大品牌排行榜2025:史沃斯稳居第一,挑战者厉邦紧随其后 - 工业清洁测评社
  • 2026年靠谱的重庆亲子农家乐/白市驿亲子采摘体验农家乐/重庆亲子研学基地/重庆周末亲子游优选推荐 - 行业平台推荐
  • 面试不慌!Java高级特性面试题全解析(附答案)
  • ComfyUI-KJNodes:基于虚拟连接与模块化设计的工作流编排引擎
  • zram 压缩内存 swap 配置实战:低内存服务器性能提升指南
  • 2026年热门的义乌拼箱代理/义乌货运代理哪家专业 - 品牌宣传支持者
  • eVTOL开发中的集成仿真系统:从模型设计到虚拟验证的工程实践
  • 从FWHM到σ:高斯波形解析中的关键几何关系与物理意义
  • C++栈与堆内存对比
  • 2026年比较好的阻燃编织网管/PPS编织网管厂家推荐与选型指南 - 行业平台推荐
  • 自监督学习在单细胞图像到组学预测中的应用与突破
  • LPC1768开发套件深度解析:从Drag2Flash到ARM Cortex-M3实战应用
  • 2026年知名的环保帆布袋/龙港帆布袋定制公司选择指南 - 品牌宣传支持者
  • 2026年口碑好的白市驿亲子烧烤游玩/重庆亲子户外休闲/重庆亲子研学基地/重庆农耕体验亲子农家乐哪家值得去 - 行业平台推荐
  • 2026年可靠的诸城硬膜拉伸热成型包装机/诸城真空拉伸膜包装机厂家精选合集 - 行业平台推荐
  • 2026永康全屋定制口碑爆棚的真相
  • 深入解析MCU定时器与PWM:从原理到实战,掌握MC68HC08AB16A TIMB模块
  • YOLO越界行为识别数据集:聚焦周界防护的实战型安防训练资源