将共享指针的派生类切换到基类
Switch Derived class of a shared pointer to base class
我目前正在尝试将存储在共享指针中的派生类的类型切换到基类。问题是Derived类继承自基类,并且模板化如下:
基本类别:
#define PRINT(s) std::cout << s << std::endl
class Base {
public:
Base() : m_a(1) {}
virtual ~Base() = default;
virtual void print() { PRINT("BASE"); }
int m_a;
};
派生类依赖于枚举模板:
enum eType { e0, e1 };
template<eType et>
class Derived : public Base { };
template<>
class Derived<e0> : public Base {
public:
Derived() { this->m_a = e0; }
void print() { PRINT("Derived e0, m_a value: " << e0 ); }
};
template<>
class Derived<e1> : public Base {
public:
Derived() { this->m_a = e1; }
void print() { PRINT("Derived e1, m_a value: " << e1 ); }
};
我的目标是有一个指向基类的共享指针,这样就可以从以下两个派生类切换:
int main()
{
std::shared_ptr<Base> sp_00 = std::make_shared<Derived<e0>> ();
std::shared_ptr<Base> sp_01 = sp_00;
sp_01->print();
std::shared_ptr<Base> sp_10 = std::make_shared<Derived<e1>> ();
*sp_01 = *sp_10;
sp_01->print();
sp_10->print();
}
与*sp_01 = *sp_10;
行一样,唯一的问题是基类的指针从派生类型Derived<e0>
切换到派生类型Derived<e1>
。然而,在我的示例中,我得到了行sp_01->print();
和行sp_10->print();
的不同结果,指示sp_01
保持为Derived<e0>
类型。
我想避免sp_01 = sp_10;
,因为它会改变指针。在上面的例子中,它将导致sp_00 != sp_01
,并且我希望sp_00
和sp_01
共享同一个对象。
我尝试用非模板派生类替换模板派生类,如下所示:
class Derived_e0 : public Base {
public:
Derived() { this->m_a = e0; }
void print() { PRINT("Derived e0, m_a value: " << e0 ); }
};
class Derived_e1 : public Base {
public:
Derived() { this->m_a = e1; }
void print() { PRINT("Derived e1, m_a value: " << e1 ); }
};
下面的代码给出了与使用模板的代码相同的结果。
int main()
{
std::shared_ptr<Base> sp_00 = std::make_shared<Derived_e0> ();
std::shared_ptr<Base> sp_01 = sp_00;
sp_01->print();
std::shared_ptr<Base> sp_10 = std::make_shared<Derived_e1> ();
*sp_01 = *sp_10;
sp_01->print();
sp_10->print();
}
所以我的问题是,如何在不改变shared_ptr本身的情况下切换由共享指针指向的派生对象(该对象在程序的其他部分中使用?(
谢谢,如果您需要更多信息,请让我知道
您不能在不重新分配sp_01
的运行时类型的情况下更改它,因为您不能将Derived<e1>
分配给Derived<e0>
(想想如果它们的大小不相同会发生什么——您已经为Derived<e0>
分配了足够的大小,而不是为Derived<e1>
分配了!(。
在我看来,你的设计(或你试图用它做的事情(在某个地方有缺陷。然而,如果你真的想在sp_00
和sp_01
之间保持"链接",你可能需要另一个"级别"的指针:
int main() {
std::shared_ptr<Base> *psp_01;
std::shared_ptr<Base> sp_00 = std::make_shared<Derived<e0>> ();
psp_01 = &sp_00;
(*psp_01)->print();
std::shared_ptr<Base> sp_10 = std::make_shared<Derived<e1>> ();
psp_01 = &sp_10;
(*psp_01)->print();
sp_10->print();
}
但是,在使用这个之前,我会对我的设计进行两次分析。
您可以dynamic_cast原始指针;类似的东西
Derived* t = dymanic_cast<Derived*>(sp_00.get())
如果不能强制转换,则会得到NULL,如果可以,则会获得有效指针。也就是说,这需要内置RTTI,这将使你的二进制文件更大,而需要这样做是你的设计不正确的标志。
- 指向基类派生类的 std::unique_ptr 的指针
- 从多个模板化基类派生时出现"隐藏重载的虚函数"警告
- 从模板基类派生是否在派生类声明的点实例化模板
- 使从一个基类派生的类能够使用继承的受保护成员
- C++多态性访问基类派生类字段
- C++派生类的设置属性到从同一基类派生的未知类对象
- 使用void* 参数定义纯虚函数的抽象基类.派生类匹配参数是指向某种类型的指针
- 在C++中,如何使用将保存从基类派生的任何对象的类成员
- 如何测试从依赖于外部系统的外部基类派生的类
- 如何从模板基类派生非模板类
- 在派生类中使用声明并不能隐藏从基类派生的相同函数
- 从具有静态结构的基类派生
- 具有从 c++ 中的非模板基类派生的模板类的事件系统
- C++ 调用从基类派生的覆盖函数
- 不清楚如何在从抽象基类派生的类中实现运算符重载
- 如何正向声明从正向声明的模板基类派生的类
- 是否可以从 std::enable_shared_from_this 和抽象基类派生
- 多态性c++,试图访问从抽象基类派生的类的成员函数
- C++多重继承,基类派生自同一类
- 基类派生类访问-如何