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

C++继承场景下基类set调用派生类get的OOP实现优化问题

问题核心缺陷

你当前的实现存在两个核心的OOP设计问题:

  • 对象切片:SortedList直接存储student基类对象,派生类的特有成员(如省份、国家、托福成绩)存入时会被直接截断,你现在手动把派生类属性同步到基类冗余字段T的写法属于临时妥协,完全没有利用继承的优势,后续要扩展派生类特有功能时完全无法实现。
  • 无多态支持:基类的getT/setT没有定义为虚函数,无法触发多态调用,手动同步字段的写法极易出错,也不符合开闭原则。
符合OOP规范的改造方案

核心思路是用基类智能指针存储多态实例,避免对象切片,同时用虚函数实现多态调用:

  1. 改造student基类为抽象基类,添加虚析构函数,将getT/setT定义为纯虚函数,删除冗余的T字段。
  2. 派生类继承基类后,override实现对应的虚函数,保留自身特有属性。
  3. SortedList改为存储std::unique_ptr<student>(或std::shared_ptr<student>),而非基类对象,从根源上避免对象切片。
  4. 读取数据时直接创建派生类实例,封装为智能指针后存入链表,无需手动同步基类字段。
核心代码示例

改造后的基类

#include <string>
#include <memory>

class student
{
    template<class T>
    friend class SortedList;
    template<class T>
    friend class Node;

public:
    student() = default;
    student(int new_Id, std::string new_FirstName, std::string new_LastName, float new_Cgpa, int new_ResearchScore)
        : FirstName(std::move(new_FirstName)), LastName(std::move(new_LastName)), cgpa(new_Cgpa), researchscore(new_ResearchScore) {}
    // 必须添加虚析构函数,避免派生类对象销毁时内存泄漏
    virtual ~student() = default;

    std::string getFirstName() const { return FirstName; }
    void setFirstName(std::string new_FirstName) { FirstName = std::move(new_FirstName); }
    std::string getLastName() const { return LastName; }
    void setLastName(std::string new_LastName) { LastName = std::move(new_LastName); }
    float getcgpa() const { return cgpa; }
    void setCgpa(float new_Cgpa) { cgpa = new_Cgpa; }
    int getresearchscore() const { return researchscore; }
    void setresearchscore(int new_ResearchScore) { researchscore = new_ResearchScore; }

    // 纯虚函数,强制派生类实现
    virtual std::string getT() const = 0;
    virtual void setT(std::string t) = 0;
    // 扩展特有属性时可加其他虚函数,比如virtual int getToeflScore() const { return 0; }

private:
    std::string FirstName;
    std::string LastName;
    float cgpa;
    int researchscore;
    // 删除冗余的T字段
};

派生类示例(国内学生)

class domesticstudent : public student
{
public:
    using student::student; // 继承基类构造函数
    domesticstudent(int the_ID, std::string The_FN, std::string The_LN, float The_cgpa, int the_RS, std::string newProvince)
        : student(the_ID, The_FN, The_LN, The_cgpa, the_RS), province(std::move(newProvince)) {}
    
    std::string getT() const override { return province; }
    void setT(std::string newProvince) override { province = std::move(newProvince); }

private:
    std::string province;
};

链表与主逻辑改造

// 链表声明改为存储基类智能指针
SortedList<std::unique_ptr<student>> list_domestic;
SortedList<std::unique_ptr<student>> list_international;

// 读取国内学生逻辑示例
auto dom_stu = std::make_unique<domesticstudent>(id, firstname, lastname, cgpa, researchscore, province);
list_domestic.listset(std::move(dom_stu));

// 读取国际学生逻辑示例
auto inter_stu = std::make_unique<internationalStudent>(id, firstname, lastname, cgpa, researchscore, country, toefl_score);
list_international.listset(std::move(inter_stu));

// 两个链表元素类型完全一致,可直接合并,调用getT时会自动触发多态返回对应属性
改造优势
  • 完全避免对象切片,派生类所有特有属性都可以完整保留,后续扩展功能不需要修改基类逻辑,符合开闭原则。
  • 基于多态的调用不需要手动同步字段,代码简洁不易出错。
  • 智能指针自动管理对象生命周期,无需手动释放内存,避免内存泄漏。
  • 两个链表元素类型统一,合并时不需要任何额外转换,完全满足你的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 23:39:01