c++ - 使用类型转换创建对 unique_ptr 中对象的引用

标签 c++ c++11 casting unique-ptr

我发现我仍然用 C 风格做很多令人尴尬的事情,所以我现在正试图通过减少对原始指针的使用来迎接新的千年。我有一个 vector unique_ptr<BaseClass> ,每个都指向派生类的一个对象。我试图找到一种很好的方法来引用派生类的一个对象。目前,我使用 .get() 来做到这一点。函数并将其转换为派生类。

但是,据我了解,.get()主要是为了与坚持使用原始指针的遗留代码进行交互,应该避免使用它。在 unique_ptr 中有另一个指向对象的指针如果可以避免,它似乎不是很好的风格。有没有办法在不使用 get 的情况下获取对派生类对象的引用?或者其他一些处理对象的方便方法?

这是一个简化的代码示例:

#include <iostream>
#include <vector>

class Fruit {
public:
    double size = 0;
    virtual ~Fruit() = default;
};

class Apple : public Fruit {
public:
    bool hasLeaf = false;
};

void doAppleStuff(std::vector<std::unique_ptr<Fruit> > &apples) {

    // assume we know that element [0] exists and it is definitely of type Apple
    auto apple = static_cast<Apple *> (apples[0].get());  // is there a better option?

    if (apple->hasLeaf) {
        std::cout << "We can leaf now" << std::endl;
    } else {
        std::cout << "We are pitiably leafless" << std::endl;
    }
}

int main() {
    std::vector<std::unique_ptr<Fruit> > fruitVec;
    auto apple = new Apple;
    apple->hasLeaf = true;
    std::unique_ptr<Fruit> applePt(apple);
    fruitVec.push_back(std::move(applePt));
    doAppleStuff(fruitVec);
    return 0;
}

(我认为有可能使用 c++14 中的 make_unique 来缩短主函数)。

做这样的事情会是好的编码风格吗?

auto &apple = *static_cast<Apple *> (apples[0].get());

答案在 "Downcasting" unique_ptr<Base> to unique_ptr<Derived>概述了一种“转换”unique_ptr 的方法通过释放它并重新创建一个新的 unique_ptr到派生类,但这在这里似乎不适用,因为我真的不想弄乱唯一指针的 vector (除非我遗漏了什么)。

最佳答案

如果您知道指针是非nullptr,则更简单的转换是:

auto& apple = static_cast<Apple&>(*apples[0]);

此语法适用于所有支持 T& operator*() const 的智能指针(例如 std::unique_ptrstd::shared_ptr, boost::intrusive_ptr).

在多重继承情况下,from-base-reference-to-derived-referencefrom-base-pointer-to-derived-pointer 更快,因为后者必须在向指针添加或减去偏移量之前始终检查 nullptr(以便 nullptr 在转换后变为 nullptr),而引用不能是 nullptr,因此不需要运行时检查。

关于c++ - 使用类型转换创建对 unique_ptr 中对象的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47671260/

相关文章:

c++ - 执行 SSE 内存复制导致堆损坏 - CRT 检查找不到任何东西

c++ - 制作C++ DLL : static variable initialization problem

c++ - 模板类是怎么匹配的

c - 省略类型定义结构的显式转换

c++ - Dijkstra的最短路径算法问题

c++ - 如果 volatile 是不必要的,为什么 std::atomic 方法提供 volatile 重载?

c++ - 值语义与具有大型数据结构的输出参数

C++ - 动态绑定(bind)和对象实例不访问派生方法

python - 尝试将字符串转换为整数的 Pandas 错误

c++ - 如何使用 Qpainter 将多个 qwidgets 打印到不同页面中的 pdf?