我目前正在尝试将存储在共享指针中的派生类的类型切换到基类。 问题是Derived类继承自Base类,并且还模板如下:
基类:
#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 ); }
};
我的目标是拥有一个指向Base类的共享指针,这样就可以从2个派生类切换如下:
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本身(在程序的其他部分使用?)
谢谢,如果您需要更多信息,请告诉我
答案 0 :(得分:1)
您无法在不重新分配sp_01
的情况下更改Derived<e1>
的运行时类型,因为您无法将Derived<e0>
分配给Derived<e0>
(想想如果这些内容不相同会发生什么情况 - 您已为Derived<e1>
分配了足够的尺寸,而不是sp_00
!)。
在我看来,你的设计(或者你试图用它做什么)在某个地方是有缺陷的。但是,如果你真的想保持一个&#34;链接&#34;在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();
}
之间,您可能需要另一个&#34;级别&#34;指针:
DECLARE
@Id varchar(80),
@Name varchar(80),
@NextId varchar(80)
BEGIN
SET @MyCursor = CURSOR FOR
SELECT id,name FROM dbo.My_TABLE
WHERE name like '%joe%';
OPEN @MyCursor
FETCH NEXT FROM @MyCursor
INTO @Id, @Name
WHILE @@FETCH_STATUS = 0
BEGIN
print 'Id is :: ' + cast(@Id as varchar(80)) + ' : ' + @Name
SELECT @NextId=id, LEAD (id,1) OVER (ORDER BY id) FROM @MyCursor;
print 'The next record is :: ' + @NextId
FETCH NEXT FROM @MyCursor
INTO @Id, @Name
END;
但是,在使用它之前,我会再次分析我的设计。
答案 1 :(得分:0)
你可以dynamic_cast原始指针;
之类的东西Derived* t = dymanic_cast<Derived*>(sp_00.get())
如果无法投射,你将获得NULL,如果可以,你将获得有效指针。也就是说,这需要内置RTTI,这将使您的二进制文件更大,并且需要这样做表明您的设计不正确。