多态中的引用和指针

时间:2015-10-26 15:26:45

标签: c++ pointers reference polymorphism

基础抽象类:

class Satellite
{
public:
    Satellite();
    virtual void center()=0;
    virtual ~Satellite(){}
};

第一个派生类

class Comm_sat:public Satellite
{
public:
    Comm_sat();
    void center() override{cout << "comm satellite override\n";}
};

第二个派生类

class Space_station:public Satellite
{
public:
    Space_station();
    void center() override{cout << "space station override\n";}
};

函数的指针版本

void f(Satellite* ms){
    ms->center();
    delete ms;
}

int main()
{
    Comm_sat* cs = new Comm_sat;
    Space_station* ss = new Space_station;
    f(cs);
    f(ss);
}

new中使用main()创建的对象在f()中被正确销毁,对吗?

功能的参考版本

void f(Satellite& ms){
    ms.center();
}

int main()
{
    Comm_sat cs;
    Space_station ss;
    f(cs);
    f(ss);
}

参考版本更好吗?

此外,我尝试使用unique_ptr,但是,我收到了错误

void f(Satellite* ms){
    ms->center();
}

int main()
{
    unique_ptr<Comm_sat> cs{new Comm_sat};
    unique_ptr<Space_station> ss{new Space_station};
    f(cs);
    f(ss);
}
  

错误:无法将参数std::unique_ptr<Comm_sat>的{​​{1}}转换为Satellite*1
  错误:输入void f(Satellite*)的{​​{1}}参数,预期指针class std::unique_ptr<Comm_sat>;

其他派生类的错误相同。

2 个答案:

答案 0 :(得分:4)

  

参考版本更好吗?

是的,虽然更好的方法是将“指针版本更糟糕”。指针版本的问题是你传递一个有效的指针,并在函数返回时获得一个悬空指针。这不直观,如果有人修改您的代码,认为您忘记删除cs中的ssmain,并未意识到f已删除,则会导致维护问题。它的论点。

在这方面,使用引用的版本要好得多,因为资源是自动管理的。您的代码的读者不需要跟踪释放csss内存的位置,因为分配和释放会自动发生。

  

我尝试使用unique_ptr,但是,我收到了错误

没有从std::unique_ptr<T>T*的隐式转换。如果要传递原始指针,则需要调用get()

f(cs.get());
f(ss.get());

答案 1 :(得分:3)

  

new中使用main()创建的对象在f()中被正确销毁,对吗?

他们被摧毁,并且正确清理,是的。 &#34;妥&#34;虽然是一个延伸,因为所有这些手动 - 新 - 删除 - 原始指针的东西都很糟糕。

unique_ptr不适合您的原因是......它是unique_ptr,而不是原始指针。你不能把它作为原始指针传递。

尝试

void f(Satellite* ms){
    ms->center();
}
// ...
f(cs.get());

或更好,除非您确实需要有时通过nullptr

void f(Satellite& ms){
    ms.center();
}
// ...
f(*cs);

或者最重要的是,因为您根本没有理由要求动态分配:

void f(Satellite& ms);
// ...
{
    Comm_sat cs;
    f(cs);
} // no new, no delete, cs goes out of scope here