这段代码让我很头疼。就个人而言,我想使用引用,因为它们比指针更整洁,所以我尝试了这个:
include "SomeClass.h"
class FooBar
{
private:
SomeClass& member_;
public:
FooBar() : member_(SomeClass()) { };
}
我已经读过你需要为类成员引用分配一个临时变量,所以在这种情况下我创建了一个虚拟的SomeClass()(我不确定我是否正在这里做。我试过它和没有指定默认构造函数)。但是,它不能在VS 2005中编译,说member_无法初始化。
我该怎么做? 提前谢谢!
答案 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}} ,则