C++ boost::shared_ptr & boost::weak_ptr &动态转换

发布于 2024-10-16 23:09:01 字数 1735 浏览 2 评论 0原文

我有这样的事情:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

可爱咩 2024-10-23 23:09:01

weak_ptr 直接转换为 weak_ptr 肯定行不通,我认为你必须将其转换为 shared_ptr然后使用shared_ptr的转换功能:

weak_ptr<Food> food = myFoodFactory->createFood(eFruit)
weak_ptr<Fruit> fruit = weak_ptr<Fruit>(dynamic_pointer_cast<Fruit>(food.lock());

Direct casting from weak_ptr<A> to weak_ptr<B> will surely don't work, I think you have to convert it to a shared_ptr and then use the casting functionality of shared_ptr:

weak_ptr<Food> food = myFoodFactory->createFood(eFruit)
weak_ptr<Fruit> fruit = weak_ptr<Fruit>(dynamic_pointer_cast<Fruit>(food.lock());
债姬 2024-10-23 23:09:01

您不能将 dynamic_castshared_ptr 一起使用,因为它需要更改对象的模板。事实上,您想要做的是内部指针上的dynamic_cast。为此,您可以对 get 返回的指针执行 dynamic_cast ,但这不会那么干净,因为引用不会被共享(与您的情况无关,因为您'使用 weak_ptr 但在使用 shared_ptr 时相关)并在此创建 share_ptr 将是未定义的,从而导致双重删除。

使用dynamic_pointer_cast来执行此操作,但两种类型仍然需要关联。换句话说,dynamic_cast(r.get()) 需要格式良好。

You cannot use dynamic_cast with shared_ptr because it would require to change the template of the object. What in fact you want to do is a dynamic_cast on the internal pointer. To do this you could do a dynamic_cast on the pointer returned by get but that would not be so clean because the reference would not be shared(irrelevant in your case since you're using weak_ptr but relevant when using shared_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 words dynamic_cast<T*>(r.get()) needs to be well formed.

疏忽 2024-10-23 23:09:01

如果您未绑定多线程,则可以使用 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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文