【问题标题】:std::map of base class pointers基类指针的 std::map
【发布时间】:2012-04-27 00:15:48
【问题描述】:

我正在编写代码来存储不同学位(目前是物理和化学)的考试结果。

我有一个抽象基类student,如下:

class student{
public:
    virtual ~student(){}
    //virtual function to add course + mark
    virtual void addresult(std::string cName,int cCode,double cMark)=0;
    //virtual function to print data
    virtual void printinfo()=0;     //to screen
    virtual void outputinfo(std::string outputfilename)=0;      //to file
};

然后我有一个物理派生类(化学方面也会有一个类似的类):

class physics : public student{
protected:
    std::string studentname;
    int studentID;
    std::map<int,course> courses; //map to store course marks
public:
    //constructors/destructors
    void addresult(std::string cName,int cCode,double cMark){course temp(cName,cCode,cMark);courses[cCode]= temp;}

    void printinfo(){
        //function to output information to screen      
    }

    void outputinfo(std::string outputfilename){
        //function to write student profile to file
    }
};    

然后,我希望有一张地图,可以在其中存储所有学生(物理和化学)。学生 ID 作为键,带有指向物理或化学的基类指针。学生是,我猜,要走的路。

我尝试了以下代码:

map<int,student*> allstudents;
physics S1(sName,sID);
physics* S2 = &S1;
allstudents.insert(pair<int,student*>(sID,S2));

但这没有用。我想我对应该指向什么有点困惑。你甚至可以用地图做到这一点吗? 如果我存储信息,是否还需要任何“清理”。这边走? 感谢您的帮助。

【问题讨论】:

  • 公共继承模拟 IS-A 关系,但物理学是一门科学,而不是学生。

标签: c++ pointers map base-class


【解决方案1】:

如果你使用一个指针超过一秒钟,你不应该在堆栈上创建对象然后指向它!下一个}一出现就消失了,你的指针也失效了!

请改用physics* S2 = new physics(sName, sID);。在地图中的所有指针上使用delete(迭代器在这里很方便)进行清理!

【讨论】:

  • 或使用smart pointers,这样您就不会因手动内存管理和异常不安全而头疼……
  • 我已经改为:physics* S1= newphysics(sName,sID); allstudents.insert(pair(sID,S1));但仍然收到错误:“c:\program files\microsoft visual studio 10.0\vc\include\utility(163): error C2440: 'initializing': cannot convert from 'physics' to 'student *'” 有什么想法吗?
  • 看起来您在某处遗漏了 *。如果您没有发现错误,请提出一个新问题。
  • 当我只使用指向类的指针(而不是指向抽象基类的指针)时产生的错误似乎更有用。在我下次尝试跑步之前,我可能应该学会走路!不过感谢您的帮助。
【解决方案2】:

你可以,但你错过了几件事:

  • 您没有遵守三原则。您还需要在类中定义赋值运算符和复制构造函数。

  • 您可能遇到内存损坏问题:

以下

physics S1(sName,sID);
physics* S2 = &S1;
allstudents.insert(pair<int,student*>(sID,S2));

S1 超出范围时,将插入一个悬空指针。您应该使用智能指针或将内存管理委托给映射 - 即当映射超出范围时使用 newdelete 创建对象。

【讨论】:

    猜你喜欢
    • 2016-02-19
    • 2013-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-25
    相关资源
    最近更新 更多