Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从函数返回具有常量成员的对象的方法_C++_Oop - Fatal编程技术网

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

C++ 从函数返回具有常量成员的对象的方法,c++,oop,C++,Oop,假设您有一个成员变量声明为常量的类 class Test { public: Test(const int const_param) : const_member_(const_param) {} private: const int const_member_; }; 我们需要一个函数,该函数将此对象的实例作为“返回值”返回 或作为“输出参数”(即传入的指针) 注意:此函数是唯一可以创建对象的函数(在上面的示例中,Foo将是唯一知道const_param值的函数,因此可以创

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

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

private:
    const int const_member_;
};
我们需要一个函数,该函数将此对象的实例作为“返回值”返回

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

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


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

我刚刚尝试了以下方法,效果很好


测试*Foo()
{
测试*x=新测试(5);
返回x;
}


我认为您不需要任何花哨的东西。

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

Foo make_foo()
{
  int n = get_mystery_value()
  Foo x(n);
  x.manipulate();
  return x;
}
如果您希望通过指针处理对象,请使用
std::shared\u ptr

std::shared_ptr<Foo> make_foo()
{
  int n = roll_dice();
  auto px = std::make_shared<Foo>(n);
  px->crazy_stuff();
  return px;
};
显然,你不能也不会说
x=make_foo(),因为您的
x
在语义上是一个常量,重新分配没有意义。

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

如果您必须通过参数返回,C++就没有能力把返回的对象放在堆栈上作为临时。因此,新对象必须位于堆上。因为在这种情况下,您想要返回的是指向对象的指针,而不是对象的内容,所以函数参数应该是可修改的指针

原始指针通常是坏消息,因为您必须记住手动适当地
删除
。智能指针类,如
unique_ptr
shared_ptr
是更好的实践,而
auto_ptr
更兼容,但使用起来更复杂

void Foo(unique_ptr< Test > &test) {
    test = new Test;
}
void Foo(唯一性测试){
测试=新测试;
}

为什么拥有一个
const
成员与拥有一个
non-const
成员有所不同?@JaredPar我认为可能是因为如果您试图将实例作为值返回,例如,
const
成员在调用
Foo()
函数之前已经初始化,然后你不能再设置
const
值了吗?只是猜测…我只能猜测OP得到了复制构造函数和赋值运算符之间的区别。当然,不能(自动)为具有常量成员的类生成赋值运算符。但是,复制构造函数没有问题,假设您正在执行Foo a=make_Foo();这是不是因为您试图进行赋值而无法生成赋值运算符,因为成员都是常量,所以无法生成赋值运算符?丁科:当然,您不能将结果赋值给现有的
Foo
,就像您不能将任何内容赋值给现有的常量一样。我认为,考虑到类的语义,不会出现这种情况。请注意,使用共享指针,您可以分配,但当然要以取消分配的对象为代价。那么如何使用此函数的结果呢?@Dinko:正如您所建议的,在初始化中:
Foo x=make_Foo();x、 做更多的事复制构造是可以的。好的,我想我开始理解了<代码>Foo x=make_Foo()实际调用复制构造函数而不是赋值运算符是否正确?
std::shared_ptr<Foo> make_foo()
{
  int n = roll_dice();
  auto px = std::make_shared<Foo>(n);
  px->crazy_stuff();
  return px;
};
int main()
{
  Foo x = make_foo();
  Foo y(make_foo());   // same thing

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

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