我有一个关于 c++ 中默认参数的问题。如果我有这样的函数:
int foo(int* obj = new Int(4)) {
/* Stuff with obj. */
}
现在,当然,整数在这里只是用作示例,但问题是我是否要为这样的参数提供一个值:
int x = 2;
foo(&x);
即使我为参数提供了一个值,因此分配了我无法再读取的内存,表达式是否仍obj = new Int(4)
计算?
使用new
表达式作为参数的默认值,如
int foo(int *obj = new int(4));
这是一个非常糟糕的主意,因为可能存在彼此行为不一致的用例,以及许多糟糕的可能结果。
假设,为了讨论起见,foo()
的实现确实
delete obj;
如果调用方执行以下任一操作,那没关系
foo(); // default argument is a new expression
foo(new int(2));
但如果调用方执行以下一项或多项操作,则会导致未定义的行为;
foo(&some_int); // some_int is a variable local to the caller
foo(new int[2]); // dynamically allocates an array
相反,假设foo()
不做delete obj
. 在这种情况下,这些语句中的任何一个
foo();
foo(new int(3));
foo(new int [2]); // dynamically allocates an array
导致内存泄漏,以及
foo(&some_int);
可能会正常工作(假设foo()
不会以其他方式调用未定义的行为)。
真正的问题是foo()
无法(在标准C++的范围内)检测调用者执行上述操作。 因此,存在未定义行为或内存泄漏的真正风险,除非调用者完全执行"正确的操作"(其中"正确的操作"意味着不会导致内存泄漏或未定义的行为)。 而且,由于有更多的选择可以做错误的事情,所以调用者可能不会做完全正确的事情。 请记住,程序员在阅读文档方面是出了名的糟糕,因此依赖文档是确保调用者(或在调用者中编写代码的程序员)执行避免上述问题所需的操作的糟糕方法。
否,仅当没有传递给默认参数时才使用默认参数。new
不会被调用,因此不会有内存分配。此外,正如一些程序员所说,如果你在函数体内部(或外部)的某个时候不清理,你就会有内存泄漏。