返回新分配的指针或通过参数更新对象

Return newly allocated pointer or update the object through parameters?

本文关键字:参数 对象 更新 指针 新分配 分配 返回      更新时间:2023-10-16

我实际上是在处理指向用户定义对象的指针,但为了简单起见,我将用整数来演示这种情况。

int* f(){
    return new int(5);
}
void f2(int* i){
    *i = 10;
}
int main(){
    int* a;
    int* b = new int();
    a = f();
    f2(b);
    std::cout << *a << std::endl;    // 5
    std::cout << *b << std::endl;    // 10
    delete b;
    delete a;
    return 0;
}

考虑在函数f()f2()中,有一些更复杂的计算来确定要返回的指针的值(f())或通过参数更新(f2())。

既然两者都有效,我想知道是否有理由选择其中一个而不是另一个?

看了这些玩具代码,我的第一个想法是将f/f2代码放入实际对象的构造函数中,并完全取消自由函数。但假设这不是一个选项,那么主要是风格/偏好的问题。以下是一些注意事项:

第一个更容易读(在我看来),因为很明显指针是一个输出值。当将(非const)指针作为形参传递时,很难一眼看出它是输入、输出还是两者兼有。

选择第一种方法的另一个原因是,如果您赞同这样一种思想,即对象应该尽可能地不可变,以便简化对代码的推理并排除线程安全问题。如果您正在尝试这样做,那么唯一真正的选择是f()创建对象,配置它,并返回const Foo*(同样,假设您不能直接将代码移动到构造函数中)。

选择第二种方法的原因是它允许您配置在其他地方创建的对象,并且对象可以是动态的或自动的。尽管这实际上是这种方法的区别——有时最好知道某种类型的对象总是在一个位置创建和初始化。

如果分配函数f()所做的事情与new相同,则只需调用new。你可以在对象的构造中进行任何初始化。

作为一般规则,尽量避免传递原始指针,如果可能的话。但是,如果对象必须比创建它的函数活得更长,则这可能是不可能的。

对于一个简单的情况,如您所示,您可以这样做:

void DoStuff(MyObj &obj)
{
    // whatever
}
int Func()
{
    MyObj o(someVal);
    DoStuff(o);
    // etc
}

f2更好,只是因为int的所有权非常清楚,而且您可以按照自己的意愿分配它。这就足够了。