You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中std::shared_ptr数组的工作原理及多态打印实现问题

实现基类智能指针指向派生类时的多态打印

嘿,作为C初学者,你选的这个练习点特别棒——多态+智能指针,这俩都是C里非常核心的知识点。咱们一步步来解决你的需求:让基类智能指针指向不同派生类对象时,能自动打印对应类的专属信息。

首先,先说说你现有代码里的小问题:你给基类定义的纯虚函数叫triangle(),这个名字只适合Triangle类,对等腰、等边三角形来说就不太合适了。咱们应该给基类定义一个通用的纯虚函数,比如printInfo(),让所有派生类都重写这个函数来输出自己的专属信息。

接下来是完整的可运行代码,我给你补全并标注了关键细节:

#include <iostream>
#include <memory>

// 抽象基类 Shape
class Shape {
public:
    // 通用纯虚函数:让所有派生类实现自己的信息打印逻辑
    virtual void printInfo() const = 0;
    // 必须声明虚析构函数!否则智能指针销毁对象时不会调用派生类析构
    virtual ~Shape() {
        std::cout << "Shape 被销毁...\n";
    }
};

// 普通三角形类,继承自 Shape
class Triangle : public Shape {
public:
    // 用 override 关键字明确重写基类虚函数,编译器会帮你检查正确性
    void printInfo() const override {
        std::cout << "我是普通三角形类,三条边长度各不相同\n";
    }
    ~Triangle() override {
        std::cout << "Triangle 被销毁...\n";
    }
};

// 等腰三角形类,继承自 Triangle
class Isosceles : public Triangle {
public:
    void printInfo() const override {
        std::cout << "我是等腰三角形类,有两条边长度相等\n";
    }
    ~Isosceles() override {
        std::cout << "Isosceles 被销毁...\n";
    }
};

// 等边三角形类,继承自 Isosceles
class Equilateral : public Isosceles {
public:
    void printInfo() const override {
        std::cout << "我是等边三角形类,三条边长度完全相等\n";
    }
    ~Equilateral() override {
        std::cout << "Equilateral 被销毁...\n";
    }
};

int main() {
    // 使用 std::unique_ptr 智能指针管理对象,无需手动释放内存
    std::unique_ptr<Shape> shape1 = std::make_unique<Triangle>();
    std::unique_ptr<Shape> shape2 = std::make_unique<Isosceles>();
    std::unique_ptr<Shape> shape3 = std::make_unique<Equilateral>();

    // 调用虚函数,自动匹配对应派生类的实现
    shape1->printInfo();
    shape2->printInfo();
    shape3->printInfo();

    // 智能指针会在main函数结束时自动销毁对象,不用写delete
    return 0;
}

关键知识点拆解

  • 多态的核心:虚函数重写:基类的纯虚函数printInfo()是多态的入口,派生类用override重写后,当基类智能指针指向派生类对象时,会自动调用对应派生类的printInfo()实现,这就是多态的魔力。
  • 虚析构函数的必要性:如果基类析构函数不是虚函数,智能指针销毁对象时只会调用基类的析构函数,派生类的资源无法正确释放,会导致内存泄漏或未定义行为。
  • 智能指针的正确用法:std::make_unique是创建unique_ptr的推荐方式,它比手动new更安全,能避免内存泄漏,而且unique_ptr会在作用域结束时自动释放对象,彻底告别手动管理内存的麻烦。

运行结果

运行这段代码后,你会看到:

我是普通三角形类,三条边长度各不相同
我是等腰三角形类,有两条边长度相等
我是等边三角形类,三条边长度完全相等
Equilateral 被销毁...
Isosceles 被销毁...
Triangle 被销毁...
Shape 被销毁...
Isosceles 被销毁...
Triangle 被销毁...
Shape 被销毁...
Triangle 被销毁...
Shape 被销毁...

销毁顺序是从最派生类到基类,这就是虚析构函数起的作用,确保每个类的析构逻辑都能被执行。

内容的提问来源于stack exchange,提问作者Const

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:15:16