C ++中自定义类型的引用成员 - 初始化它们

时间:2009-07-01 06:17:14

标签: c++ reference

这段代码让我很头疼。就个人而言,我想使用引用,因为它们比指针更整洁,所以我尝试了这个:

include "SomeClass.h"

class FooBar 
{
   private:
     SomeClass& member_;

   public:
     FooBar() : member_(SomeClass()) { };
}

我已经读过你需要为类成员引用分配一个临时变量,所以在这种情况下我创建了一个虚拟的SomeClass()(我不确定我是否正在这里做。我试过它和没有指定默认构造函数)。但是,它不能在VS 2005中编译,说member_无法初始化。

我该怎么做? 提前谢谢!

6 个答案:

答案 0 :(得分:4)

您只能将temp绑定到const引用。所以如果你把它改成

const SomeClass& member_;
你会没事的。

你可能不想要这个;你应该只将member_声明为值,而不是引用,或者,如果你想将它作为引用,你可能想要传入对构造函数的引用,比如

FooBar(SomeClass& sc) : member_(sc) { };

答案 1 :(得分:3)

1)初始化后,无法将引用更改为指向另一个对象。

你真的需要这种行为吗?

2)使用临时对象初始化引用时,在此临时对象之后。对象超出了您的引用无效的范围。

这就是你的代码不正确的原因。你现在有无用的成员。我建议考虑两种选择

a)考虑使用指针而不是引用。

b)将构造函数更改为以下内容:

MyClass(type & a):membmer_(a){...}

答案 2 :(得分:2)

你绝对不希望在构造函数中设置引用吗?即。

FooBar(SomeClass& sc) : member_(sc) {};

如果没有,并且您将在稍后设置它,那么我认为指针是您最好的选择,尽管不是“整洁”。

请参阅here

答案 3 :(得分:2)

根据标准,您不能将非const引用存储到临时变量。在构造函数中创建SomeClass()对象时,它是一个临时对象,并且您尝试将其存储为非const引用。顺便说一下,我认为这里不需要参考。您只需将其存储为SomeClass member_;

即可

答案 4 :(得分:1)

此成员是否需要是指针或引用?尽管您的界面可能已经简化,但您似乎并不打算将SomeClass的实例传递给FooBar的构造函数。这是引用有用的地方,因为您保证类使用的实例与给它的实例相同。

如果您打算将SomeClass封装在FooBar中,那么以下内容就足够了。

include "SomeClass.h"

class FooBar 
{
  private:
    SomeClass member_;

  // ... rest of your implementation ...
  // default ctor/dtor is sufficient.
}

此代码将在SomeClass实例化时实例化FooBar实例。类析构函数(由编译器生成)将负责释放为成员_分配的堆栈内存。

答案 5 :(得分:1)

简短回答:正如Jesse指出的那样,您可能想要使用值成员或指针,但不是这个具体示例中的引用。

答案很长:C ++的内存模型更像是C,而不像Java。对象可以存在

    在堆栈上
  • 。这是参数和局部变量的情况。
  • 在堆上。使用new创建的所有对象都是这种情况。
  • 在数据段中。这些是你的全局变量。
  • 将其他对象作为值成员。

与此相反,在Java中,除了基本类型和指针(在Java中称为引用)之外,所有对象都使用new创建并存在于堆栈中。这种更简单的内存模型对Java来说已经足够了,因为它有垃圾收集器,可以自动销毁未使用的对象。

标准C ++没有垃圾收集器。在以下情况下删除对象:

  • 当“它超出范围”时删除基于堆栈的对象,
  • 在应用程序终止时删除全局对象
  • 删除包含对象时删除其他对象中包含的对象,但
  • 开发人员必须使用delete手动删除堆上的对象。

由于此手动内存管理容易出错,因此通常会在C ++应用程序中的对象之间定义强大的所有权策略。

回到您的问题,您希望确保只要您的member_ - 对象存在,就可以访问FooBar。因此,如果member_不是FooBar的所有者或其他类似的密切相关的对象,只要FooBar - 对象存在就保证存在,那么你可能会这样做不想使用参考。

在你的例子中,我会使用

    如果我想到包含 FooBar的{​​{1}} ,则
  • 值成员,
  • 指针否则。