C++ 多态性中的引用和指针
基本抽象类:C++ 多态性中的引用和指针,c++,pointers,reference,polymorphism,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";} }; c
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";}
};
在main()
中使用new
创建的对象在f()
中正确销毁,对吗
函数的参考版本
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);
}
void f(Satellite& ms){
ms.center();
}
int main()
{
Comm_sat cs;
Space_station ss;
f(cs);
f(ss);
}
参考版本更好吗
此外,我尝试使用unique\u 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);
}
void f(卫星*ms){
ms->center();
}
int main()
{
独特的{新通信卫星};
独特的{新空间站};
f(cs);
f(ss);
}
错误:无法将参数1
的std::unique\u ptr
转换为Satellite*
到void f(Satellite*)
错误:输入
class std::unique_ptr
参数指定给delete
,预期指针delete cs
另一个派生类的错误相同
参考版本更好吗
是的,尽管更好的说法是“指针版本更差”。指针版本的问题在于,您向它传递了一个有效指针,并在函数返回时得到一个悬空指针。这是不直观的,当有人认为您忘记了删除main
中的cs
和ss
而没有意识到f
删除了它的参数时,就会导致维护方面的麻烦
在这方面,使用引用的版本要好得多,因为资源是为您自动管理的。代码的读取器不需要跟踪cs
和ss
的内存释放位置,因为分配和释放是自动进行的
我尝试使用unique\u 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
到T*
的隐式转换。如果要传递原始指针,需要调用:
f(cs.get());
f(ss.get());
在main()
中使用new
创建的对象在f()
中正确销毁,对吗
它们被摧毁了,并且被正确地清理了,是的。“正确”是一种延伸,因为所有这些手动新建和删除原始指针的东西都是糟糕的风格
unique\u ptr
不适合您的原因是。。。它是一个唯一的\u ptr
,不是原始指针。你不能把它当作一个原始指针来传递
试一试
或者更好,除非您有时确实需要通过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
void main
是不允许的。如果我理解正确,在任何一种情况下(指针或引用),对象都是在堆上分配的,而不是在堆栈上分配的,对吗?@MiloLu使用引用的版本在堆栈上分配cs
和ss
对象。正如建议的那样,我可以在堆上分配对象,并且仍然通过引用传递*cs
和*ss
。在我看来,地址只是一个地址,不管它在堆上还是在堆栈上。@MiloLu这取决于你。在堆栈上进行分配的一个优点是,您不需要跟踪对象的生存期并调用delete
。堆栈分配的缺点是,您无法将对象的生存期延长到已分配对象的块的运行时之后。除此之外,堆栈比堆快,这再次使引用版本成为首选?