C++ boost::shared_ptr & boost::weak_ptr &动态转换
我有这样的事情:
enum EFood{
eMeat,
eFruit
};
class Food{
};
class Meat: public Food{
void someMeatFunction();
};
class Fruit: public Food{
void someFruitFunction();
};
class FoodFactory{
vector<Food*> allTheFood;
Food* createFood(EFood foodType){
Food* food=NULL;
switch(foodType){
case eMeat:
food = new Meat();
break;
case eFruit:
food = new Fruit();
break;
}
if(food)
allTheFood.push_back(food);
return food;
}
};
int foo(){
Fruit* fruit = dynamic_cast<Fruit*>(myFoodFactory->createFood(eFruit));
if(fruit)
fruit->someFruitFunction();
}
现在我想更改我的应用程序以使用 boost shared_ptr 和weak_ptr,以便我可以在一个地方删除我的食物实例。它看起来像这样:
class FoodFactory{
vector<shared_ptr<Food> > allTheFood;
weak_ptr<Food> createFood(EFood foodType){
Food* food=NULL;
switch(foodType){
case eMeat:
food = new Meat();
break;
case eFruit:
food = new Fruit();
break;
}
shared_ptr<Food> ptr(food);
allTheFood.push_back(ptr);
return weak_ptr<Food>(ptr);
}
};
int foo(){
weak_ptr<Fruit> fruit = dynamic_cast<weak_ptr<Fruit> >(myFoodFactory->createFood(eFruit));
if(shared_ptr<Fruit> fruitPtr = fruit.lock())
fruitPtr->someFruitFunction();
}
但问题是dynamic_cast似乎不适用于weak_ptr
我如何从weak_ptr
中获取weak_ptr
> 如果我知道它指向的对象是派生类型?
I have something like this:
enum EFood{
eMeat,
eFruit
};
class Food{
};
class Meat: public Food{
void someMeatFunction();
};
class Fruit: public Food{
void someFruitFunction();
};
class FoodFactory{
vector<Food*> allTheFood;
Food* createFood(EFood foodType){
Food* food=NULL;
switch(foodType){
case eMeat:
food = new Meat();
break;
case eFruit:
food = new Fruit();
break;
}
if(food)
allTheFood.push_back(food);
return food;
}
};
int foo(){
Fruit* fruit = dynamic_cast<Fruit*>(myFoodFactory->createFood(eFruit));
if(fruit)
fruit->someFruitFunction();
}
now I want to change my application to use boost shared_ptr and weak_ptr such that i can delete my food instance in a single place. it would look like this:
class FoodFactory{
vector<shared_ptr<Food> > allTheFood;
weak_ptr<Food> createFood(EFood foodType){
Food* food=NULL;
switch(foodType){
case eMeat:
food = new Meat();
break;
case eFruit:
food = new Fruit();
break;
}
shared_ptr<Food> ptr(food);
allTheFood.push_back(ptr);
return weak_ptr<Food>(ptr);
}
};
int foo(){
weak_ptr<Fruit> fruit = dynamic_cast<weak_ptr<Fruit> >(myFoodFactory->createFood(eFruit));
if(shared_ptr<Fruit> fruitPtr = fruit.lock())
fruitPtr->someFruitFunction();
}
but the problem is that the dynamic_cast doesn't seem to work with weak_ptr
how do I get a weak_ptr<Fruit>
out of a weak_ptr<Food>
if i know that the object it points to is of derived type?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
从
weak_ptr
直接转换为weak_ptr
肯定行不通,我认为你必须将其转换为shared_ptr
然后使用shared_ptr的转换功能:Direct casting from
weak_ptr<A>
toweak_ptr<B>
will surely don't work, I think you have to convert it to ashared_ptr
and then use the casting functionality of shared_ptr:您不能将
dynamic_cast
与shared_ptr
一起使用,因为它需要更改对象的模板。事实上,您想要做的是内部指针上的dynamic_cast
。为此,您可以对get
返回的指针执行dynamic_cast
,但这不会那么干净,因为引用不会被共享(与您的情况无关,因为您'使用weak_ptr
但在使用shared_ptr
时相关)并在此创建 share_ptr 将是未定义的,从而导致双重删除。使用
dynamic_pointer_cast
来执行此操作,但两种类型仍然需要关联。换句话说,dynamic_cast(r.get())
需要格式良好。You cannot use
dynamic_cast
withshared_ptr
because it would require to change the template of the object. What in fact you want to do is adynamic_cast
on the internal pointer. To do this you could do adynamic_cast
on the pointer returned byget
but that would not be so clean because the reference would not be shared(irrelevant in your case since you're usingweak_ptr
but relevant when usingshared_ptr
) and creating a share_ptr on this would be undefined resulting on a double delete.Use
dynamic_pointer_cast
to do this but the two types still need to be related. In other wordsdynamic_cast<T*>(r.get())
needs to be well formed.如果您未绑定多线程,则可以使用 BOOST_DISABLE_THREADS 来提高性能,请参阅 https://stackoverflow.com/a/8966130/1067933
you can use BOOST_DISABLE_THREADS to improve performance if you're not bound to multithreading, see https://stackoverflow.com/a/8966130/1067933