c++ - 使用 std::unique_ptr/std::shared_ptr const 正确组合

标签 c++ pointers c++14 constants const-correctness

目前我想知道如何正确使用 std::unique_ptr作为关于 const 正确性的成员变量。

以下示例允许更改 my_foo 拥有的内容尽管是常量:

#include <iostream>
#include <memory>

struct foo {
    foo() : value_ptr_(std::make_unique<int>(3)) {}
    void increment() const {
        ++(*value_ptr_);
    }
    int get_value() const {
        return *value_ptr_;
    }
    std::unique_ptr<int> value_ptr_;
};

int main() {
    const foo my_foo;
    std::cout << my_foo.get_value() << std::endl;
    my_foo.increment(); // But my_foo is const!
    std::cout << my_foo.get_value() << std::endl;
}

替换 std::make_unique<T>std::make_unique<const T>乍一看似乎是一个很好的解决方案。但是,这不允许更改 my_foo 的内容即使它是非常量:

#include <iostream>
#include <memory>

struct foo {
    foo() : value_ptr_(std::make_unique<int>(3)) {}
    void increment() {
        ++(*value_ptr_);
    }
    int get_value() const {
        return *value_ptr_;
    }
    std::unique_ptr<const int> value_ptr_;
};

int main() {
    foo my_foo;
    std::cout << my_foo.get_value() << std::endl;
    my_foo.increment(); // compiler error
    std::cout << my_foo.get_value() << std::endl;
}

在这个最小的例子中有一个指向 int 的指针当然不是很有意义,但在实际代码中 unique_ptr可以持有指向多态对象的基类的指针,即我们无法简单地按值存储的对象。

那么如何更好地处理这种情况呢?

最佳答案

可以继承std::unique_ptr并仅覆盖 3 个(unique_ptr<T[]> 为 4 个)方法,提供常量/非常量重载:

template <typename T>
struct propagating_unique_ptr : std::unique_ptr<T> {
    using unique_ptr<T>::unique_ptr;
    using unique_ptr<T>::operator =;

    const T *get() const noexcept {
        return unique_ptr<T>::get();
    }
    T *get() noexcept {
        return unique_ptr<T>::get();
    }

    const T &operator *() const noexcept {
        return unique_ptr<T>::operator *();
    }
    T &operator *() noexcept {
        return unique_ptr<T>::operator *();
    }

    const T *operator -> () const noexcept {
        return unique_ptr<T>::get();
    }
    T *operator -> () noexcept {
        return unique_ptr<T>::get();
    }
}; 

关于c++ - 使用 std::unique_ptr/std::shared_ptr const 正确组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46399388/

相关文章:

c++ - 类对象指针不会分配给字符串

c - 为什么我得到这样一个数组的长度?

c++ - GNU C++ 编译器 ((GCC) 5.2.0) 本身擅长 "inlining"吗?

c++ - 为什么与 "end()"迭代器进行比较是合法的?

c++ - L 和 R 引用变量

C++11:正确的 std::array 初始化?

c++ - 创建一个简单的可移植位掩码并使用它

c++ - switch 语句 C++ 和 glut

c++ - 为什么C++语言的malloc函数前面要写指针类型?

c++ - 在 log4cxx 中使用 utf-8 字符