2016-02-05 127 views
0

所以我想要做的就是存儲:對象B和對象B對象的引用沒有指針

  • 對象B在對象A和對象B的對象A的
  • 參考

雖然不使用指針。

使用指針和引用我試圖避免的唯一區別是訪問語法。我不想寫「 - >」每次我在對象B.訪問對象的時間

我認爲可以工作,但會引發分割故障代碼:

#ifndef A_H 
#define A_H 

class B; 
class A{ 
    B b; 
public: 
    A(); 
}; 
#endif 

了Bh

#ifndef B_H 
#define B_H 

class A; 
class B{ 
    A& a; 
public: 
    B(A &_a); 
}; 
#endif 

A.cpp

#include "A.h" 
#include "B.h" 

A::A():b(B(*this)){} 

B.cpp

#include "B.h" 
#include "A.h" 

B::B(B &_b):a(_b){}  

我還以爲是造成分段錯誤使用「這」在初始化列表(uninititialized實例)的關鍵字,但我讀過,只要我不訪問它的第一件事一切都應該沒問題。我的構造函數是空的,所以我不會發生什麼錯誤。

是否可以做到這一點類似於我在做什麼?如果沒有,那麼爲什麼,有什麼可以讓我不寫' - >'?

編輯: 的確有,因爲它只是寫成僞代碼只是讓任何人都沒有浪費時間,這裏不再粘貼不必要的代碼一些編譯錯誤。編寫僞代碼當然編譯完成。 But goo.gl/DHlM6X

但現在它運行沒有seg故障。我想我的項目中有一些我做的不同。我將不得不測試一下爲什麼它在項目中不起作用,我會發布什麼問題,以便問題可以有真正的答案。

+0

此代碼編譯? – NathanOliver

+0

如果我拼寫正確,那麼是的,在archblock下的codeblocks C++ 11中。 – Antua

+1

有趣。 AFAIK A.h不應該編譯,因爲您有一個常規變量爲不完整類型。 – NathanOliver

回答

1

起初,在這裏使用引用而不是亂七八糟的指針似乎是個不錯的主意,但是你並沒有幫助你自己。爲什麼?引用意味着鏈接到一個對象,您可以確定鏈接對象的壽命長於引用。

所以,你的代碼

class B{ 
    A& a; 
}; 

基本規定:「對於B類型的每一個對象有A類型的已知,不可改變對象B類型創建的對象之前存在,並仍將住在B -object被破壞的時間「。

同時你的代碼

class A{ 
    B b; 
}; 

指出:「A類型的每個對象由B類型的對象的」,這主要是告訴編譯器爲A類型的對象分配內存(包括B b的空間),然後在該內存中的正確位置構造一個類型爲B的對象,然後構造一個類型爲A的對象。但在本例中A被乙之後建造之前銷燬B.

兩個語句相互排斥。

因此,無論您切換到指針(其中國家「的對象知道X類型的關於另一個對象」,可以是nullptr),或者你可以考慮做這樣的事情:

class Combined{ 
    A a; 
    B b; 
} 

,然後添加功能需要了解Combined類中的兩個對象。

在標準我發現下面的關於您的問題,爲什麼它不應該在所有的工作:

9.3.2 this指針[class.this]
在的身體非靜態(9.3)成員函數,關鍵字 是一個prvalue表達式,其值是調用該函數的對象的地址。在類別X的成員函數 中的這種類型是X *。如果成員函數被聲明爲const(...)

因此,從我可以說,this只有定義了「在非靜態成員函數體內」的行爲。一些編譯器允許this,typeid(this)sizeof(this)也在該類的其他部分,但我無法在標準中找到它。

+0

我認爲內存分配恰好在構造函數被觸發之前發生,因此A在創建B時有內存。直到B結束其初始化,它才引用B,然後A可以完成其初始化寫入引用到正確的位置。我的程序保證從頭到尾都有兩個對象,所以不需要改變引用或存儲nullptr。 組合課只會做很多混亂,因爲兩個班只做不同的事情,但必須互相轉達。我寧願使用指針:/ 仍然你的答案是迄今爲止最好的答案。 – Antua

+0

是的,內存分配發生在構造函數被觸發之前。但是直到施工結束,它只是空的(或未初始化的)內存。所以順序應該是這樣的:-A的內存被分配--Ab使用指向A的指針構造--A使用任何在你的構造器體內構造的。這意味着在構造A之前使用指向A的指針。這可能適用於某些編譯器,但我不會推薦它,因爲它不保證可以在所有編譯器上工作(至少從我讀過的標準中)。 – Anedar