带有派生类的C++共享指针
我试图从派生类获取基类的共享指针。代码如下:带有派生类的C++共享指针,c++,c++11,pointers,shared-ptr,C++,C++11,Pointers,Shared Ptr,我试图从派生类获取基类的共享指针。代码如下: class Base { public: typedef std::shared_ptr<Base> Ptr; Base(); Base(const Base& orig); virtual Ptr getShared() = 0; }; class Derived : public Base { public: // default constructor and co
class Base {
public:
typedef std::shared_ptr<Base> Ptr;
Base();
Base(const Base& orig);
virtual Ptr getShared() = 0;
};
class Derived : public Base {
public:
// default constructor and copy constructor
virtual Base::Ptr getShared() {
return std::make_shared<Derived>(this);
}
};
我试图用它来得到Base::Ptr的向量,如下所示:
std::vector<Base::Ptr> objects;
Derived d;
objects.push_back(d.getShared());
我遇到了复制构造函数的问题,我知道这与试图在幕后投射指向引用的指针来破坏常量的正确性有关。我只是不能确定原因是什么,或者我做了一个错误的假设。有什么想法吗
Base.h:20:5:注意:参数1从“Base*”的转换未知
to'const Base&'Base.h:19:5:note:candidate:Base::Base
编辑:
塞维林的回答让我找到了解决这个问题的正确方法。Sahu的答案是正确的,但我试图让多个对象共享单个对象的指针。如果您需要对同一对象进行多个引用,而无需构造其他实例,则可以从中启用\u共享\u。需要注意的是,第一次调用指针上的make_shared会实现您预期的效果,但随后使用同一指针的调用会使用指针作为构造函数的参数构造该对象的其他实例。正确使用enable_shared_from_这将返回一个共享_ptr,该共享_ptr与引用该对象的所有其他共享_ptr共享访问权限
编辑2:为了完整起见,这种情况实际上是由于误解了通过引用传递和通过指针传递之间的区别造成的。在这种特殊情况下,真正的问题是应用程序中其他地方的设计决策。为其他有类似问题的人提供食物。std::make_的签名在C++17之前共享
template< class T, class... Args >
shared_ptr<T> make_shared( Args&&... args );
无效,因为无法构造从派生的*派生的类型的对象。您需要将该行更改为:
return std::make_shared<Derived>(*this);
它返回一个共享的\u ptr,该ptr封装了一个新复制构造的派生对象。问题在这一行:
virtual Base::Ptr getShared() {
return std::make_shared<Derived>(this);
}
看起来你想要这个,而不是这个。你不应该用这个吗?这就像建议某人学习开车,蒙着眼睛开车,以避免看到可怕的交通或交通状况。你认为蒙着眼睛开车会有什么结果?看看吧,这是一个更有用的方向。@Cheersandhth.-Alf,更好吗?是的,如果OP的代码被修复了,它实际上会做什么更清楚。但是启用来自的共享对我来说很重要,因为代码的意图很明显。我认为这才是真正的答案-@干杯-阿尔夫,不能那样做。只允许在以前共享的对象上,即在std::shared_ptr管理的对象上,从_this调用shared_。嗯,对我来说已经很晚了,但除非我觉得累了,否则至少有两种方法可以处理。A强制动态分配,例如,通过使析构函数受保护并使用自定义删除器,或B在对象未动态分配时生成不带op deleter的共享\u ptr。最后一个很难看。shared_ptr的要点是具有保证生存期的共享所有权,而这种保证将被打破,因此有可能通过悬空指针访问不再存在的对象。但我认为A是好的。
virtual Base::Ptr getShared() {
return std::make_shared<Derived>(this);
}
virtual Base::Ptr getShared() {
return std::shared_ptr<Base>(this);
}