如何在C++中实现类似C#的多态数组或多态Vector?
在C++中实现多态数组/向量
在C++中,直接用基类类型的数组或std::vector存储派生类对象会触发对象切片(派生类特有的数据和行为会被截断),无法实现多态。必须通过指针或智能指针来存储基类引用,才能保留派生类的完整特性。
首先确保基类的read函数是虚函数,这是C++实现多态的核心前提:
#include <iostream> #include <vector> #include <memory> // 智能指针头文件 // 基类 class item { public: // 虚函数,必须声明为virtual(纯虚或带默认实现) virtual void read() const { std::cout << "Reading an item\n"; } // 基类必须有虚析构函数,避免内存泄漏 virtual ~item() = default; }; // 派生类book class book : public item { public: void read() const override { // override关键字确保重写虚函数 std::cout << "Reading a book\n"; } }; // 派生类periodical class periodical : public item { public: void read() const override { std::cout << "Reading a periodical\n"; } };
方案1:使用原始指针数组
和你提供的C#代码结构最接近的实现,注意最后要手动释放内存:
int main() { // 定义存储基类指针的数组,大小100 item* items[100]; // 填充派生类对象的指针 items[0] = new book(); items[1] = new periodical(); // 剩余位置设为nullptr,避免野指针 for (int i = 2; i < 100; ++i) { items[i] = nullptr; } // 遍历调用read(),触发多态 for (int i = 0; i < 100; ++i) { if (items[i] != nullptr) { // 跳过空指针 items[i]->read(); } } // 手动释放内存,避免泄漏 for (int i = 0; i < 100; ++i) { delete items[i]; } return 0; }
方案2:使用智能指针的std::vector(推荐)
std::unique_ptr或std::shared_ptr可以自动管理内存,不需要手动delete,更安全:
int main() { // 定义存储unique_ptr<item>的向量 std::vector<std::unique_ptr<item>> items; // 添加派生类对象,emplace_back直接构造,避免拷贝 items.emplace_back(std::make_unique<book>()); items.emplace_back(std::make_unique<periodical>()); // 范围for循环遍历,调用read() for (const auto& ptr : items) { ptr->read(); } // 不需要手动释放内存,unique_ptr会在vector销毁时自动清理 return 0; }
关键注意点
- 基类必须声明虚析构函数:如果基类没有虚析构,用基类指针delete派生类对象时会触发未定义行为。
- 虚函数必须用
virtual声明:派生类重写时可以加override关键字,编译器会帮你检查是否正确重写了基类的虚函数。 - 优先使用智能指针:避免手动管理内存带来的泄漏风险,
std::unique_ptr是最适合的选择(独占所有权),如果需要共享所有权可以用std::shared_ptr。
内容的提问来源于stack exchange,提问作者Brandon Wright
相关产品推荐
相关产品推荐

