2009-11-09 39 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