2009-11-09 60 views
13
struct Div 
{ 
    int i; 
    int j; 
}; 

class A 
{ 
    public: 
      A(); 
      Div& divs; 
}; 

在我的構造函數的定義,我有以下初始化需要一個臨時變量C++

A::A() : divs(NULL) 
{} 

我收到以下錯誤:

Error72 error C2354: 
    'A::divs' : initialization of reference member requires a temporary variable 

回答

33

必須初始化引用來引用某個東西;它不能引用任何東西,所以你不能默認構造一個包含一個類的類(除非像別人所說的那樣,你定義了一個全局的「null」值)。你需要的是被賦予Div指一個構造函數:

explicit A(Div &d) : divs(d) {} 

如果你希望它能夠成爲「空」,那麼你需要一個指針,而不是一個參考。

+1

通常情況下,您不能使用引用成員默認構建類。例如,引用可以綁定到在名稱空間範圍(「全局」對象,以簡單的詞語)聲明的對象。 – AnT 2009-11-09 15:00:11

+1

如上所述,如果您使用預定義變量(如以下示例中所示),則可以執行默認構造函數。 – 2009-11-09 15:04:19

+2

你們都是對的。但是,我建議不要使用全局「null」值 - 它不能是const,所以默認行爲是使用一個全局對象,任何其他類的實例都可以更改,恕不另行通知。 – 2009-11-09 15:52:32

8

首先,你可以」 t有一個NULL引用。其次,一個類中的所有變量引用必須在構造時初始化。

+0

如何糾正呢? – aajkaltak 2009-11-09 14:42:07

+0

@varun:您需要在構造時(即在構造函數中)初始化對有效對象實例的引用。 – jldupont 2009-11-09 14:43:39

+1

@varun:請注意,如果這可以讓您的生活更輕鬆或重構,那麼您可以使用指針。 – jldupont 2009-11-09 14:54:41

5

在「英文」中:引用是指東西。它不能參考什麼也沒有(null)。這就是爲什麼引用更安全地使用指針。

+5

不只是英文。在C++中完全相同。 – jalf 2009-11-09 15:32:09

+1

大聲笑,我的意思是「用普通英語寫的C++規則」;-) – Abel 2009-11-09 15:59:39

12

divs是一個引用,而不是指針。你不能將它設置爲NULL,它必須指向某種實際的對象。在這裏做的最好的事情可能是定義一個靜態/全局的Div實例,你可以將其任意定義爲「Null Div」(將它的值設置爲你不太可能使用的),並初始化div。像這樣的東西:

struct Div 
{ 
    int i; 
    int j; 
}; 

Div NULL_DIV = { INT_MAX, INT_MAX }; 

class A 
{ 
    public: 
      A(); 
      Div& divs; 
}; 


A::A() : divs(NULL_DIVS) 
{ 
} 

或者,或者,只是使div指針,而不是引用。

*請注意,除非拋棄常量,否則不能使用const引用,因爲默認情況下,編譯器不允許將cosnt ref分配給非const ref。

+0

你正在用const對象初始化非const的ref。它是否編譯? – Arkadiy 2009-11-09 15:16:52

+0

啊,很好,不,不。我會更新答案。 – 2009-11-09 15:25:09

3

參考文獻必須引用一些東西。在C++語言中沒有這樣的空引用。如果該成員可能沒有值,那麼它應該是一個指針,或者是一個類似於這樣的類型。

必須初始化引用以引用有效的對象。

3

請記住,一旦引用被初始化爲指向某個東西,就不能將其改爲指向其他東西。如果這不是所需的行爲,那麼應該使用指針或對象的副本。

1

正如其他帖子所述,參考文獻(Div &)不能爲空。所以你可以做的最直接的改變是在構造函數中提供一個引用並初始化你的引用成員。與此類似,

class A 
{ 
    public: 
      A(Div& inDivs); 
      Div& divs; 

}; 

public A::A(Div& inDivs) 
: divs(inDivs) 
{} 
3

編譯器的消息是,不從語言角度是有意義的,但揭示了編譯器的內部工作,該序列中,其內在邏輯的作品的消息之一。

在你的情況下,你正在使用一個右值(NULL)來初始化一個引用。當這種初始化被允許時,右值被轉換爲臨時對象,引用將被綁定到該臨時對象。因此,編譯器馬上就意識到了這一點,並通過診斷信息告知了您這一事實。

但實際上,這樣的技巧只允許用於const引用,所以你的代碼被破壞了,因爲在我們的例子中引用不是const。此外,struct引用(如代碼中的引用)不能使用NULL右值(它具有整型)進行初始化,所以它也因爲這個原因而被破壞。

雖然編譯器的信息頗具誤導性。該消息的文本似乎意味着用臨時對象初始化成員引用是非法的。事實上,這在C++中是合法的(一旦上述問題得到解決),雖然它沒有意義。但是,我想,一旦形成不良的代碼是伴隨着至少一些錯誤信息,它應該是爲大家好......

2

簡單明瞭:

參考不能爲空。

1
class A 
{ 
    Div & ref(Div div) { return div; } 
    public: 
     A() : divs(ref(Div())) {}; 
     Div& divs; 
}; 
+0

雖然這段代碼可能會回答這個問題,但提供關於爲什麼和/或如何回答問題的附加背景會顯着提高其長期價值。 請編輯您的答案以添加一些解釋。 – gevorg 2016-06-09 11:46:17

0

我建議:

class A{ 
    std::deque<object*>& que = *(std::deque<object*> *)0; 
    // ... 
    // Of course `que` is to be assigned valid deque before using it - just like pointers... 
}; 
+1

請在您的代碼中添加一些文字,以說明您爲什麼會提示它。這個問題已經有了一個可以接受的答案,所以爲什麼你的答案是有效的/更好的解釋會有很大的幫助。 – Banana 2014-07-28 15:49:21

+0

對不起,我不明白爲什麼我必須解釋使用此解決方案的原因 - 除非它表明它的工作原理。 – Bretzelus 2014-10-30 20:24:28

+0

它可能在某些實現中有效,但不符合。如果你想要一個指針,只需要使用一個指針,而不是完全違背引用意圖的這樣的詭計。 – 2017-03-28 06:32:19