簡體   English   中英

轉換為沒有 unique_ptr 的派生 class

[英]Cast to derived class without unique_ptr

背景

我正在使用 Bison 和 Flex 創建一個 Cpp 解析器,但偶然發現了一個問題:在我的解析器中,我需要一個基本 class 對象的向量,比如說形狀 根據派生的 class 和 object 有哪個,我需要訪問不同的成員。 因此,我打算將unique_ptr存儲在向量中。 然后在訪問時,我可以動態地將它們轉換為它們的派生類型。

問題

但是,我無法讓 Bison 正確處理 unique_ptrs。 無論我如何指定parser.yy文件,在編譯時我都會遇到類似的錯誤

usr/include/c++/9/bits/stl_uninitialized.h:127:72:錯誤:static 斷言失敗:結果類型必須可從輸入范圍的值類型構造

根據這篇文章,Bison 不能很好地處理 unique_ptrs (據我所知,Bison 內部不使用std::move() ),我認為情況仍然如此。

我的問題

因為我想保持 class 層次結構不變並且不想修復 Bison 本身的錯誤:從基礎 class 投射到派生的 ZA2F2ED4F8EBC2CBB4C21A29DC40AB6 時,是否有使用 unique_ptrs 的替代方法?

代碼示例

特別是,我希望在不使用 unique_ptrs 的情況下進行以下操作。

enum Shape_type{
    SHAPE_TYPE_CIRCLE,
    SHAPE_TYPE_TRIANGLE,
};

class Shape{
public:
    enum Shape_type type;
    Shape(enum Shape_type type){ this->type=type; }
    virtual ~Shape(){}
};

class Circle: public Shape{
    int r;
public:
    int get_r(){ return this->r; }
    Circle(int r):Shape(SHAPE_TYPE_CIRCLE){ this->r=r; }
};

int main(void){
    std::vector<std::unique_ptr<Shape>> shapes;
    std::unique_ptr<Shape> circle_ptr = std::make_unique<Circle>(42);
    shapes.push_back(std::move(circle_ptr));
    
    for(auto& s_ptr: shapes){
        switch(s_ptr->type){
        case SHAPE_TYPE_CIRCLE:
        {
            auto c = dynamic_cast<Circle&>(*s_ptr);
            std::cout << "circle with r=" << c.get_r() << std::endl;
            break;
        }
        default: {
            std::cout << "other shape" << std::endl;
            break;
        }
        }
    }
    
    return 0;
}

非常感謝任何幫助。 提前致謝。

多態方式是(用std::shared_ptr替換不可復制的std::unique_ptr ):

class Shape{
public:
    virtual ~Shape() = default;
    virtual void draw() const = 0;
};

class Circle: public Shape
{
    int r;
public:
    explicit Circle(int r): r(r) {}
    int get_r() const { return r; }

    void draw() const override { std::cout << "circle with r=" << r << std::endl; }
};

class Square: public Shape
{
    int side;
public:
    explicit Square(int side): side(side) {}
    int get_side() const { return side; }

    void draw() const override { std::cout << "square with side=" << side << std::endl; }
};

int main()
{
    std::vector<std::shared_ptr<Shape>> shapes { std::make_shared<Circle>(42) };
    
    for (const auto& shape_ptr: shapes)
    {
        shape_ptr->draw();
    }
    return 0;
}

使用std::variant ,您可能會這樣做

class Circle
{
    int r;
public:
    explicit Circle(int r): r(r) {}
    int get_r() const { return r; }

    void draw() const { std::cout << "circle with r=" << r << std::endl; }
};

class Square
{
    int side;
public:
    explicit Square(int side): side(side) {}
    int get_side() const { return side; }

    void draw() const { std::cout << "square with side=" << side << std::endl; }
};

using Shape = std::variant<Circle, Square>;

int main()
{
    std::vector<Shape> shapes { Circle(42) };
    
    for (const auto& shape: shapes)
    {
        std::visit([](const auto& shape){ shape.draw(); }, shape);
    }
    return 0;
}

暫無
暫無

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

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