在C/C++中使用堆栈进行内存管理时的编码风格

Gra*_*rav 2 c c++ memory stack

来自Java背景,我正在尝试学习如何以最简单的方式处理C/C++中的内存(de)分配.

一位同事建议我只为成员变量分配内存,让堆栈处理局部变量.我不完全确定这个概念是什么,但它意味着函数将像这样实现:

void inc(int x, int &y){
  y=x+1;
}
Run Code Online (Sandbox Code Playgroud)

另一种方式是这样的:

int inc(int x, int &y){
  y=x+1;
  return y;
}
Run Code Online (Sandbox Code Playgroud)

第一个禁止我在表达式中使用它,即:

int y;
inc(2,y); 
inc(y,y);
Run Code Online (Sandbox Code Playgroud)

第二个确实如此,但它并不漂亮:

int y;
y=inc(inc(2,y),y);
Run Code Online (Sandbox Code Playgroud)

在我搞砸我的代码之前,经验丰富的C/C++程序员对这种编码风格有何看法?

Lig*_*ica 5

我会非常沮丧

int inc(int x, int &y) {
   y=x+1;
   return y;
}
Run Code Online (Sandbox Code Playgroud)

对于使用此函数的程序员,不清楚为什么函数修改输入并返回值,它们都是同一个对象.


真的,在我看来,选择是在:

// #1
void inc(int x, int& y) {
   y=x+1;
}

int y = 0;
inc(2, y);
Run Code Online (Sandbox Code Playgroud)

// #2
int inc(int x) {
   return x+1;
}

int y = inc(2);
Run Code Online (Sandbox Code Playgroud)

在一般情况下,我仍然喜欢,#2因为我发现"out参数"过时和笨重使用.正如你所指出的那样,你最终会挣扎于表达式,并且当你调用函数1时,实际上发生了什么并不是非常清楚.

再说一次,如果你有一个比一个更复杂的对象int(比如一个数组或一个大类,或者你只是想"返回"多个对象),那么如果你不是,它可能会使对象所有权更容易处理在函数内创建任何新对象,使#1选择更方便.

我想我在这里得出的结论是,它取决于场景.试图概括这些事情是一个愚蠢的错误.


1 - 使用指针而不是引用解决了一些问题,虽然它确实引入了膨胀,现在不得不费心检查无效指针:

// #3
void inc(int x, int* y) {
   assert(y); // at least, we can check that it's not NULL
   *y = x+1;
}

int y = 0;
inc(2, &y); // clear here that I'm passing a pointer
Run Code Online (Sandbox Code Playgroud)