2014-09-13 51 views
-2

考慮這個代碼的假設是一個結構有一些國家和int state標誌,這種狀態是任何複雜的:不可移動的結構?

struct Object 
{ 
private: 
    int state = 0; 

public: 
    Object(Object&& other): 
     state(std::move(other.state)) 
    {} 
}; 

struct ReferencingObject 
{ 
private: 
    Object& object; 
    int  state = 0; 

public: 
    ReferencingObject(Object& object): 
     object(object) 
    {} 

    ReferencingObject(ReferencingObject&& other): 
     object(other.object), 
     state(std::move(other.state)) 
    {} 
}; 

struct CannotMove 
{ 
    Object    object; 
    ReferencingObject ref; 

    CannotMove(): 
     object(), 
     ref(object) 
    {} 

    CannotMove(CannotMove&& other): 
     object(std::move(other.object)), 
     ref(std::move(other.ref)) 
    {} 
}; 

1)着眼於CannotMove(CannotMove&&)移動構造函數,我認爲我目前的實施是錯誤的,因爲移動ReferencingObject實例保持對現在未定義的Object實例的引用,因爲它已經移動。但是,由於ReferencingObject結構體包含它自己的狀態,我的結論是CannotMove不存在正確的移動構造函數。我的結論是否正確?

2)現在假設我從1)得出的結論是正確的,並且CannotMove是一個相當複雜的模板類。複雜,以至於獲得實例(但從用戶的角度)的唯一合理的方法是通過使用auto,如:

auto cannotMoveInstance = createCannotMove(); 

createCannotMove()功能可以寫的方式,將允許編譯器執行copy elision並從1)完全解決這個問題。但是,爲了防止代碼的用戶意外地移動CannotMove的實例,應將移動構造函數標記爲已刪除。但是,這會阻止編譯器使用複製elision。我是不是被迫放棄的auto使用和直接通過

CannotMove instance; 

創建我的實例?

編輯1ObjectReferencingObject的數據成員爲私有,以更好地反映典型的OOP編程。

+0

'std :: move()''int'沒有意義。 – 2014-09-13 20:53:49

+0

「CannotMove不存在正確的移動構造函數,我的結論是否正確?」如果你不解釋這個班應該做什麼,怎麼會有人回答這個問題? – 2014-09-13 20:59:25

+0

@ T.C .:我知道,因此我的問題中的第一句話 – 2014-09-13 21:17:05

回答

0

您的類別不變似乎是ref中的參考始終是指我自己的object

要保持這種不變性,編寫CannotMove的移動構造函數的正確方法是移動Object,然後自己構造ReferencingObject以引用您自己的對象。首先給ReferencingObject一個構造函數,它從ReferencingObject &&的狀態移動,但將引用設置爲不同的Object

ReferencingObject(ReferencingObject&& other, Object & obj): 
    object(obj), 
    state(std::move(other.state)) 
{} 

則:

CannotMove(CannotMove&& other): 
    object(std::move(other.object)), 
    ref(std::move(other.ref), object) 
{ } 

如果你堅持有作爲編寫的代碼,那麼沒有,沒有邏輯上正確的方式來寫的CannotMove一個構造函數,因爲你ReferencingObject暴露給任何接口移動狀態但不復制參考。有辦法通過改變CannotMove的定義來解決這個問題(例如,直接存儲智能指針Object而不是Object),但由於您不想改變其他任何東西,所以不能完成。

如果刪除移動構造函數,則不能返回CannotMove,並且必須直接構造。

+0

我更新了代碼,以反映典型的OOP編程風格,其中數據成員是私人的 – 2014-09-13 21:18:22

+0

是的,這將工作,但您已通過更改'ReferencingObject'的行爲修改了問題。 – 2014-09-13 21:27:08

+0

@DaliborFrivaldsky那麼,如果您不更改它,那麼這就是你的設計的一個問題 - 如果你想保持自我引用,那麼你不能只是「複製」引用。 – 2014-09-13 21:30:03