C ++ boost :: shared_ptr & boost :: weak_ptr & dynamic_cast - PullRequest
3 голосов
/ 10 февраля 2011

У меня есть что-то вроде этого:

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, похоже, не работает со слабым_ptr

как мне получить weak_ptr<Fruit> из weak_ptr<Food>если я знаю, что объект, на который он указывает, имеет производный тип?

Ответы [ 3 ]

4 голосов
/ 10 февраля 2011

Прямое приведение от weak_ptr<A> к weak_ptr<B>, безусловно, не будет работать, я думаю, вам нужно преобразовать его в shared_ptr, а затем использовать функцию приведения в shared_ptr:

weak_ptr<Food> food = myFoodFactory->createFood(eFruit)
weak_ptr<Fruit> fruit = weak_ptr<Fruit>(dynamic_pointer_cast<Fruit>(food.lock());
0 голосов
/ 23 января 2012

вы можете использовать BOOST_DISABLE_THREADS для повышения производительности, если вы не связаны с многопоточностью, см. https://stackoverflow.com/a/8966130/1067933

0 голосов
/ 10 февраля 2011

Вы не можете использовать dynamic_cast с shared_ptr, потому что для этого потребуется изменить шаблон объекта. Что вы на самом деле хотите сделать, так это dynamic_cast на внутреннем указателе. Чтобы сделать это, вы могли бы сделать dynamic_cast для указателя, возвращенного get, но это было бы не так чисто, потому что ссылка не была бы общей (не имеет значения в вашем случае, поскольку вы используете weak_ptr, но уместна при использовании shared_ptr) и создание share_ptr будет неопределенным, что приведет к двойному удалению.

Используйте dynamic_pointer_cast, чтобы сделать это, но эти два типа все еще должны быть связаны. Другими словами dynamic_cast<T*>(r.get()) должен быть хорошо сформирован.

...