7

このコードがコンパイルされるとは思っていませんでした:

#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 のインスタンスが定数である場合、エンジンも同様に定数であってはならないのはなぜですか? それが共有ポインタであれば、私はそれでまったく問題ありませんでした。

私が望む動作を反映できるスマートポインターはありますか?

4

1 に答える 1

20

それはとても簡単です:

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>();

オブジェクトは定数ですが、ポインターではありません。

ところで:あなたが話している「const-propagation」は、あなたが述べたのと同じようにC++にも当てはまります。

于 2015-11-06T11:01:55.160 に答える