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;
}