从函数返回具有常量成员的对象的方法

时间:2011-09-08 22:26:16

标签: c++ oop

假设您有一个成员变量声明为常量的类。

class Test
{
public:
    Test(const int const_param) : const_member_(const_param) {}

private:
    const int const_member_;
};

我们想要一个将该对象的实例作为“返回值”

返回的函数
Test Foo();  
Test* Foo();     
Test& Foo();

或作为“输出参数”(即传入的指针)。

void Foo(Test* test);
void Foo(Test** test); // maybe this is more correct?

请注意,此函数是唯一可以创建对象的函数(在上面的示例中,Foo将是唯一知道const_param的值的函数,因此可以创建Test } object)

做这样的事情最好的方法是什么?这甚至可能吗?

3 个答案:

答案 0 :(得分:2)

你可以通过复制返回这样的对象,除非你有充分的理由避免这种设计:

Foo make_foo()
{
  int n = get_mystery_value()
  Foo x(n);
  x.manipulate();
  return x;
}

如果您更愿意通过指针处理对象,请改为使用std::shared_ptr<Foo>

std::shared_ptr<Foo> make_foo()
{
  int n = roll_dice();
  auto px = std::make_shared<Foo>(n);
  px->crazy_stuff();
  return px;
};

或者,如果您只需要一个处理程序对象,请使用std::unique_ptr<Foo>


一点解释:在对象中拥有一个常量成员本质上意味着该对象本身具有常量对象的语义。 复制常量是可以的,但不能重新分配它们,因此在典型的用例中,您只需创建一次此类的对象,而不是重新分配它。将自动为您定义复制构造函数,因此您可以直接说出:

int main()
{
  Foo x = make_foo();
  Foo y(make_foo());   // same thing

  x.twiddle();
  y.skedaddle();

  // ...
}

显然你不能也不会说x = make_foo();,因为你的x在语义上是一个不变的,重新分配是没有意义的。

答案 1 :(得分:0)

我刚刚尝试了以下内容,它运行正常。

Test* Foo()
{
Test* x = new Test(5);
return x;
}

我觉得你不需要任何花哨的东西。

答案 2 :(得分:0)

工厂函数(具有创建特定类型对象的专有权的函数)应该使用该类型作为其返回,而不是“通过参数返回”。

如果必须通过参数返回,则C ++无法将返回的对象作为临时对象放在堆栈中。因此,新对象必须在堆上。因为在这种情况下,指向对象的指针,而不是它的内容,是你想要返回的,函数参数应该是一个可修改的指针。

原始指针通常是坏消息,因为您必须记住适当地手动delete。智能指针类(例如unique_ptrshared_ptr)是更好的做法,auto_ptr更兼容,但使用起来比较棘手。

void Foo(unique_ptr< Test > &test) {
    test = new Test;
}