2010-07-07 112 views
0

我有一个基类(Base),其构造函数的参考作为参数。在我的派生类的构造函数中,我调用超类的构造函数,当然我需要传递一个引用作为参数。但我必须获得其中的返回类型是值的方法这样的说法......C++:引用作为构造函数参数,帮助

我会给出一个简单的例子:

class Base 
{ 
public: 
    Base(MyType &obj) { /* do something with the obj */} 
}; 

class Derived : public Base 
{ 
public: 
    Derived(MyOtherType *otherType) : 
     Base(otherType->getMyTypeObj()) // <--- Here is the error because (see *) 
    { 
     // * 
     // getMyTypeObj() returns a value and 
     // the Base constructor wants a reference... 
    } 
}; 

class MyOtherType 
{ 
public: 
    MyType getMyTypeObj() 
    { 
     MyType obj; 
     obj.setData(/* blah, blah, blah... Some data */); 
     return obj; // Return by value to avoid the returned reference goes out of scope. 
    } 
}; 

我怎样才能解决这个问题?

+0

基础构造函数是否修改对象,对其进行引用?有什么限制?我的意思是,代码中的哪些部分可以修改,哪些部分必须保持不变? – 2010-07-07 16:05:07

+2

使参数成为常量引用。 – 2010-07-07 16:06:24

+0

const引用如何提供帮助?它仍然是一个不再存在的东西的参考。 – 2010-07-07 16:31:36

回答

3

更改基类: class Base { public: Base(const MyType &obj) { /* do something with the obj */} };

更新:如果要修改的obj你不能明显地有const参考。在这种情况下,您可以:

1)按值传递参数。这将会产生副本的开销,但是避免以后必须明确释放它。

2)更改MyOtherType::getMyTypeObj()

MyType& MyOtherType::getMyTypeObj() 
{ 
    MyType* obj = new MyType(); 
    obj->setData(/* blah, blah, blah... Some data */); 
    return *obj; 

}

在这种情况下,要记住删除对象,你用它做了。

+2

这将工作,除非'/ *做obj * /'意味着他想修改obj。 – 5ound 2010-07-07 16:27:58

+0

当然,这是超载派上用场的地方:) – Cogwheel 2010-07-07 16:47:25

+0

当然。但是,如果他想修改对象,他可能会更好地制作自己的副本。更新了我的答案。谢谢 – 341008 2010-07-07 17:20:24

0

该问题是由GetMyTypeObj()返回基于堆栈的'obj'副本引起的,因此编译器在构造函数中创建了一个临时变量,其范围仅仅是Base()构造函数。

1

认真吗?你的问题有答案。将参数的类型更改为Base构造函数,或者更改getMyTypeObj()的返回值的类型,以使这些类型兼容。

+0

+1:它好像是你的所有代码,那么为什么解决方法可以解决一个问题? – rubenvb 2010-07-07 17:05:24

0

在我看来,有两种方法可以解决这个问题。

  1. 更改Base构造函数以通过值而不是通过引用接受MyType对象。这将复制临时对象并解决范围问题。

  2. 或者,您可以在Derived中创建一个MyType对象的副本并传递对该对象的引用。

class Derived : public Base 
{ 
public: 
    Derived(MyOtherType *otherType) : 
     Base(m_myType) , 
     m_myType(otherType->getMyTypeObj()) 
    { 
     // ... 
    } 
private: 
    MyType m_myType; 
}; 

选项1是简单,我一般会推荐它。
选项2是为了防止其他约束条件阻止您更改基础构造函数,