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

如果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的實例是不斷,爲什麼不引擎應該是恆定的呢?如果這是一個共享指針,我會完全正確的。

有沒有可以反映我想要的行爲的智能指針?

+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:你所說的「常量傳播」也適用於C++,就像你說的那樣。

+0

是的,很清楚,對於只有一個問題內部提出太多問題感到抱歉。其中之一確實是這樣的:爲什麼C++委員會爲其提供了一個獨特的智能指針,就像C原始指針一樣?這背後的理由是什麼? – nyarlathotep108

+1

@ nyarlathotep108:在開始的時候,它似乎是一個無意義的東西,直到你意識到一個指針只不過是另一個發生在另一個對象地址上的對象。有時候你想把指針改爲其他地方的指針,但它可能指向常量對象。在這種情況下(它們很常見),這種模式可以節省您的工作。 – 3442

+0

我現在沒有發現它有用,但我看到你的觀點可能是有效的。也許當我希望他們的行爲與引用行爲一樣時(從const的正確性角度來看),我會寫自己獨特的指針,我看不到其他任何方式。 – nyarlathotep108