【问题标题】:Unique pointer and const correctness唯一指针和 const 正确性
【发布时间】:2015-11-06 10:53:27
【问题描述】:

我没想到这段代码会编译:

#include <iostream>
#include <memory>

class A
{
public:

    inline int get() const
    {
        return m_i;
    }

    inline void set(const int & i)
    {
        m_i = i;
    }

private:

    int m_i;
};

int main()
{
    const auto ptr = std::make_unique< A >();

    ptr->set( 666 ); // I do not like this line    D:<
    std::cout << ptr->get( ) << std::endl;

    return 0;
}

如果 ptr 是一个原始的 C 指针,我可以接受。但由于我使用的是智能指针,我无法理解其背后的基本原理。

我使用唯一指针来表达所有权,在面向对象编程中这可以看作是一种对象组合(“部分”关系)。

例如:

class Car
{
    /** Engine built through some creational OO Pattern, 
        therefore it has to be a pointer-accessed heap allocated object **/
    std::unique_ptr< Engine > m_engine;
};

或者:

class A
{
    class Impl;

    std::unique_ptr< A::Impl > m_impl; // PIMPL idiom
};

如果 Car 类的实例是常量,为什么引擎也不应该是常量?如果它是一个共享指针,我完全可以接受。

有没有可以反映我想要的行为的智能指针?

【问题讨论】:

  • ptr-&gt;set( 666 ); // I do not like this line D:&lt;: 每日报价 ;).

标签: c++ pointers smart-pointers const-correctness object-composition


【解决方案1】:

很简单:

const auto ptr = std::make_unique< A >();

这意味着指针本身是不变的!但它持有的对象不是。你可以看到它以相反的方式工作......

A *const ptr = new A();

都是一样的。指针是常量(不能修改为指向别处),但对象不是。

现在,您可能的意思是您想要这样的东西,不是吗?

const auto ptr = std::make_unique<const A>();

这将创建一个指向常量A 的常量指针。

还有这个办法……

auto ptr = std::make_unique<const A>();

对象是常量,但不是指针。

顺便说一句:您所说的“常量传播”也适用于 C++,就像您所说的那样。

【讨论】:

  • 是的,这很清楚,很抱歉在一个问题中问了太多问题。其中之一确实是:为什么 C++ 委员会制作了一个独特的智能指针,其行为方式就像 C 原始指针一样?这背后的原理是什么?
  • @nyarlathotep108:一开始,这似乎是无意义的,直到您意识到指针只是另一个对象,它恰好保存了另一个对象的地址。有时您想将指针更改为指向其他地方,但它可能指向常量对象。在这种情况下(尽管它们很常见),这种模式会挽救你的工作。
  • 我现在不觉得它有用,但我认为你的观点可能是有效的。也许当我希望它们以与引用相同的方式运行时(从 const 正确性的角度来看),我将编写自己的唯一指针,我看不到任何其他方式。
  • 我看不出有任何反对 auto ptr = std::make_unique&lt;const A&gt;(); 的理由。 OP 的意图是不通过指针修改对象,但他很可能想重新安装它。
  • @MM:你是对的。我不记得我在写这篇文章时在想什么,所以删除了那个笔记。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-19
相关资源
最近更新 更多