我试图从shared_ptr<void>
施放。我知道它是shared_ptr<A>
或shared_ptr<B>
,但我找不到如何检查它是哪一个。
A和B是2个不相关的类。
我想做点什么:
//x.valuePtr is a shared_ptr<void>
if(x.valuePtr is shared_ptr<A>){
... do things with the pointer to an A object
} else if (x.valuePtr is shared_ptr<B>){
... do things with the pointer to an B object
}
我有一个属性(我无法更改的类),类型为shared_ptr<void>
。
在大多数情况下,我知道哪个是指针的真实类型,所以我可以毫无问题地使用static_pointer_cast
。例如:
// If I know x.valuePtr is shared_ptr<A>
x.valuePtr = std::make_shared<A>();
// I can use static_pointer_cast somewhere else in the application and it works fine
std::shared_ptr<A> a_ptr = std::static_pointer_cast<A> (x.valuePtr);
// Same happens when I know it is a shared_ptr<B>
x.valuePtr = std::make_shared<B>();
std::shared_ptr<B> b_ptr = std::static_pointer_cast<B> (x.valuePtr);
但现在我遇到了问题,因为它可能是其中之一(shared_ptr<A>
或shared_ptr<B>
)。如果我使用static_pointer_cast<A>
(或<B>
),该行编译并抛出没有异常,但是一旦我尝试使用来自casted ptr的特定内容(如果它是错误的类型)它会抛出异常。例如:
// If x.valuePtr is shared_ptr<A>
x.valuePtr = std::make_shared<A>();
// But if I try to cast it to shared_ptr<B> somewhere in the application where it could be shared_ptr<A> or shared_ptr<B>
std::shared_ptr<B> b_ptr = std::static_pointer_cast<B> (x.valuePtr); // this does no fail
// It throws an exception when I try to use b_ptr. For example
b_ptr->AMethodInB();
我尝试在static_pointer_cast
之后进行不同的检查(对于null,空shared_ptr
等),但似乎没有任何效果:
x.valuePtr = std::make_shared<A>();
std::shared_ptr<B> b_ptr = std::static_pointer_cast<B> (x.valuePtr);
if(b_ptr == NULL || b_ptr.get() == NULL || !b_ptr){
"It never gets into this line"
"I would be able to try to cast it to shared_ptr<A>"
}
b_ptr->AMethodInB(); // and keeps failing here
我也尝试使用dynamic_pointer_cast<B>
,但没有编译(&#34; error: cannot dynamic_cast .... (source is not a pointer to class)
&#34;)。另外,我发现无法dynamic_cast
FROM void
here
我有什么方法可以检查static_pointer_cast
是否真的有效?
或者以某种方式检查此shared_ptr<void>
的实际类型?
PD:我使用的是c ++ 11,gcc 4.8.2。
答案 0 :(得分:0)
如果您需要提供类型信息,我对使用std::shared_ptr<void>
感到奇怪。
可能最好使用基于模板的方法(某种名称是类型特征)?
struct A
{
int id;
};
struct B
{
int id1;
};
//Default template (neither A or B)
template<typename T>
struct Checker
{
enum { isA = 0, isB = 0 };
};
//Template for A
template<>
struct Checker<A>
{
enum { isA = 1, isB = 0 };
};
//Template for B
template<>
struct Checker<B>
{
enum { isA = 0, isB = 1 };
};
//Convenience function (only thing it does in runtime is compare 2 ints)
template<typename T>
bool checkA(std::shared_ptr<T> p)
{
return Checker<T>::isA == 1;
}
//Convenience function (only thing it does in runtime is compare 2 ints)
template<typename T>
bool checkB(std::shared_ptr<T> p)
{
return Checker<T>::isB == 1;
}
//Convenience function
template<typename T>
void test(std::shared_ptr<T> p)
{
std::cout
<< "is A : " << checkA(p)
<< " is B : " << checkB(p) << std::endl;
}
void test()
{
//This is working
std::shared_ptr<A> a = std::make_shared<A>();
std::shared_ptr<B> b = std::make_shared<B>();
test(a);
test(b);
//This is not working
std::shared_ptr<void> a1 = std::make_shared<A>();
std::shared_ptr<void> b1 = std::make_shared<B>();
test(a1);
test(b1);
}
输出结果为:
is A : 1 is B : 0
is A : 0 is B : 1
is A : 0 is B : 0
is A : 0 is B : 0
答案 1 :(得分:0)
您应该为Base
和A
创建公共基类(B
)。然后可以将shared_ptr<void>
转换为shared_ptr<Base>
,将static_pointer_cast<Base>(...)
和dynamic_pointer_cast
结果转换为A
或B
。
通过向do_things
添加纯虚拟成员函数Base
并在A
和B
中使用{... do things with the pointer to an A object
覆盖它,可能会更好地避免动态强制转换。 1}}和... do things with the pointer to a B object
。