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

Ways to return objects with constant members from a function

本文关键字:成员 对象 方法 常量 函数 返回      更新时间:2023-10-16

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

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对象)

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

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

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在语义上是一个常量,对它重新赋值是没有意义的。

我刚刚尝试了以下操作,它工作得很好。

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

我想你不需要什么花哨的东西。

工厂函数(具有创建特定类型对象的独占权限的函数)应该使用该类型作为返回值,而不是"按参数返回"。

如果必须通过实参返回,c++没有办法将返回的对象作为临时对象放在堆栈上。因此,新对象必须在堆上。因为在这种情况下,要返回的是指向对象的指针,而不是对象的内容,所以函数实参应该是一个可修改的指针。

原始指针通常是坏消息,因为您必须记得手动正确地设置delete。智能指针类,如unique_ptrshared_ptr是更好的实践,auto_ptr更兼容,但使用起来更棘手。

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