簡體   English   中英

從shared_ptr到weak_ptr多態性的轉換

[英]Conversion from shared_ptr to weak_ptr polymorphism

我在解決這一問題時遇到了麻煩。 假設我有這個向量

std::vector<std::shared_ptr<Car>> cars; 

汽車是一個抽象類。 我希望能夠返回不同類型的弱指針,因此我要執行以下操作。

template<typename T>
    std::weak_ptr<T> GetCar()
    {
        for (std::vector<std::shared_ptr<Car>>::iterator it = cars.begin(); it != cars.end(); ++it)
        {
            T* derived = dynamic_cast<T*>((*it).get());
            if (derived != nullptr)
            {
                std::weak_ptr<T> carPointer = *it;
                return carPointer;
            }
        }
        return std::weak_ptr<T>();
    }

但是,當我嘗試將函數與從Car繼承的類一起使用時,出現以下錯誤。 Error C2440 'initializing': cannot convert from 'std::shared_ptr<Car>' to 'std::weak_ptr<Saab>'當詢問它時,可能沒有有效的汽車。 我嘗試使用boost :: optional但它不能處理多態。 如果我無法使用它,我可能會使用原始指針。

您不能直接從shared_ptr<Car>構造weak_ptr<Saab> ,因為模板參數Car必須隱式轉換為Saab才能正常工作。

但是您可以先將您的shared_ptr<Car>轉換為shared_ptr<Saab> ,然后再構造您的weak_ptr 在下面的示例中,我使用了std::dynamic_pointer_cast來執行此操作。

這是我想出的:

#include <iostream>
#include <vector>
#include <memory>

struct Car
{
    virtual void name() = 0;
};

struct Saab : Car
{
    virtual void name() { std::cout << "Saab" << std::endl; }   
};

struct Renault : Car
{
    virtual void name() { std::cout << "Renault" << std::endl; }   
};

template<typename T>
std::weak_ptr<T> GetCar(std::vector<std::shared_ptr<Car>> cars)
{
    for (std::vector<std::shared_ptr<Car>>::iterator it = cars.begin(); it != cars.end(); ++it)
    {
        auto derived = std::dynamic_pointer_cast<T>(*it);
        if (derived != nullptr)
        {
            std::weak_ptr<T> carPointer(derived);
            return carPointer;
        }
    }
    return std::weak_ptr<T>();
}

int main()
{
    std::vector<std::shared_ptr<Car>> cars;
    cars.push_back(std::make_shared<Saab>());
    cars.push_back(std::make_shared<Renault>());

    auto wp = GetCar<Saab>(cars);

    auto sp = wp.lock();
    if (sp)
    {
        sp->name();
    }

    auto wp2 = GetCar<Renault>(cars);

    auto sp2 = wp2.lock();
    if (sp2)
    {
        sp2->name();
    }

}

它輸出:

薩博

雷諾

Coliru鏈接: http ://coliru.stacked-crooked.com/a/9dbb85b556b83597

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM