2015-12-16 96 views
3

一個類的抽象成員應該是指針還是引用?類的抽象成員應該是指針還是引用?

對於玩具的例子,比如說我有下面的類:

class SerializedFileProcessor { 
public: 
    std::string Process(std::string file) const { 
     std::string text = deserializer.Deserialize(file); 
     text = processor.Process(text); 
     return serializer.Serialize(text); 
    } 

private: 
    IDeserializer? deserializer; 
    IProcessor? processor; 
    ISerializer? serializer; 
}; 

凡解串器,處理器和串行器(具體子類的實例)都傳遞到這個類的構造函數。

SerializedFileProcessor不擁有這些,不應刪除它們。

這些類成員應該是指針還是引用?或者這種模式應該完全不同?

+3

我不認爲這與抽象性有關。 – djechlin

+1

我可能會誤解,但由於類型IW是抽象的,數據不能被複制到SerializedFileProcessor中。這是我指定他們是抽象類的唯一原因。 – Mistodon

+0

如果您能夠使用引用,請始終將它們優先於指針。 –

回答

-3

如果你的班級沒有他們,它不應該是一個參考。使用指針並讓擁有者持有std::unique_ptr

+0

「如果你的班級沒有他們,它不應該是一個參考。」這是不明/錯誤的。 C++中沒有引用。 –

+0

其實它是相反的,如果它擁有它必須是一個指針(原始或智能) – Slava

1

這幾乎是hello-world依賴注入(/ inversion)的例子。

有一個類似的問題在這裏,不同的解決方案:Dependency injection in C++11 without raw pointers

編輯:我搬到我從這裏原來的答覆到這個問題。


原來的答覆與SerializedFileProcessor例如:

只是使用指針(智能或原始的),或甚至一個普通的C++參考,所述的一面是,它們允許呼叫從一個const非const方法上下文。

我提出了一個與std::reference_wrapper(它缺少const安全訪問器)類似但不相同的包裝。將T*替換爲unique_ptrshared_ptr以獲得擁有版本(也添加默認移動構造)。

template<typename T> 
    struct NonOwningRef{ 
    NonOwningRef() = delete; 
    NonOwningRef(T& other) noexcept : ptr(std::addressof(other)) { }; 
    NonOwningRef(const NonOwningRef& other) noexcept = default; 

    const T& value() const noexcept{ return *ptr; }; 
    T& value() noexcept{ return *ptr; }; 

    private: 
    T* ptr; 
    }; 

用法:

class SerializedFileProcessor { 
public: 
    std::string Process(std::string file) const { 
     std::string text = deserializer.value().Deserialize(file); 
     text = processor.value().Process(text); 
     return serializer.value().Serialize(text); 
    } 

private: 
    NonOwningRef<IDeserializer> deserializer; 
    NonOwningRef<IProcessor> processor; 
    NonOwningRef<ISerializer> serializer; 
}; 
+0

謝謝!這是一個非常有用的鏈接。我不知道爲什麼我沒有想到將我的問題更多地轉向DI。 – Mistodon

0

它們可以是,你只能確保使用之前引用的對象不會死(即一般的壽命應該超過SerializedFileProcessor壽命)。

引用成員有一個缺點 - 實際上不可能創建一個賦值運算符(所以如果你需要一個,那麼你需要一個指針 - 即使對於具有引用成員的類也有實際賦值的技巧,但是他們非常討厭)。如果它們是可選的,那麼它們需要是指針(引用不是可選的)。

相關問題