5

私がコンパイルし、このコードを期待していなかった。ユニークなポインタとconstの正しさ

#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; 
} 

生CのポインタだったPTR場合、私はそれでOKでしょう。しかし、私はスマートポインタを使用しているので、私はこれの背後にある根拠を理解できません。

という所有権を表すオブジェクト指向プログラミングでは、これはオブジェクトの構成(部分的な関係)とみなされる可能性があります。例えば

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 
}; 

クラスの車のインスタンスが定数であれば、なぜエンジンは同様に一定であるべきではないのですか?それが共有ポインタだったら私はそれで完全にうまくいっていたでしょう。

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

+1

'ptr-> set(666); //私はこの行が好きではありませんD:<':今日の見積もり;)。 – 3442

答えて

11

は、それはかなり簡単です:これは、ポインタ自体が一定であることを意味

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

オブジェクトがポインタ一定ではなく、この他の方法もあります。

BTW:「const-propagation」はC++にも当てはまります。

+0

はい、それは1つの質問の中であまりにも多くの質問をして申し訳ありません、明らかでした。それらのうちの1つは確かにありました。なぜ、C++委員会がCの生のポインタのように動作するように、ユニークなスマートポインタが作られたのですか?この背後にある根拠は何ですか? – nyarlathotep108

+1

@ nyarlathotep108:ポインタは、別のオブジェクトのアドレスを保持する別のオブジェクトであることがわかるまで、最初は非意味的です。ポインターを他の場所を指すように変更したい場合がありますが、定数オブジェクトを指していることがあります。この場合(かなり一般的ですが)、このパターンはあなたの仕事を節約します。 – 3442

+0

今は役に立たないが、あなたの意見はおそらく有効なものだと思う。たぶん、リファレンスが(constの正確さの観点から)動作するのと同じように動作させたい場合、私は自分のユニークなポインタを書きますが、他の方法は見えません。 – nyarlathotep108