【发布时间】:2021-07-06 10:58:27
【问题描述】:
我见过其他人使用它,它看起来很聪明,但我不确定这是好还是坏的做法。它可以工作,而且我个人喜欢它的工作方式,但是在更大的程序范围内这样做真的有用吗?
他们所做的是在实际函数参数中动态分配一些数据类型,并在函数中删除它。这是一个例子:
#include <iostream>
class Foo {
private:
int number;
public:
Foo(int n) : number(n) { }
int num() { return number; }
Foo* new_num (int i) { number = i; }
};
void some_func (int thing, Foo* foo);
int main() {
std::cout << "Enter number: ";
int n;
std::cin >> n;
some_func(n, new Foo(0)); // <-- uses the 'new' operator with a function argument
return 0;
}
// calculates difference between 'thing' and 'n'
// then puts it inside the Foo object
void some_func (int thing, Foo* foo) {
std::cout << "Enter another number: ";
int n;
std::cin >> n;
std::cout << "Difference equals " << foo->new_num(thing - n)->num() << std::endl;
delete foo; // <-- the Foo object is deleted here
}
我知道可以在函数参数中使用运算符,但我只知道使用级别 2、4 到 15 和 17 的运算符以及赋值运算符 ? :、@ 987654324@ 和 --、一元 + 和 -、!、~、* 和 &、sizeof 和演员表。像这样的东西:
foo((x < 3)? 5 : 6, --y * 7);
bar(player->weapon().decr_durability().charge(0.1), &shield_layers);
所以,我实际上有两个问题。
-
new-as-an-argument 是好的做法吗? -
如果
new有效,显然任何返回类型的运算符都有效,是否正在使用这些良好做法?::、new []、throw、sizeof...、typeid、noexcept、alignof
【问题讨论】:
-
(1) 通常没有 - 所有权不明确。 (2) 太笼统的问题。尽量避免在所有程序中使用
new/delete,它们几乎总是可以替换为std::vector<T>或拥有智能指针(通常为std::unique_ptr)或只是范围块中的临时对象{ .... } -
我见过其他人使用它,它看起来很聪明, -- 显然你正在查看 Java 或 C# 程序员编写的代码(以一种糟糕的方式) 来编写 C++ 代码。使用
new创建对象是这种情况发生的迹象。 -
在这种情况下,您应该只传递
foo的值,因为创建它并在之后立即删除它没有任何好处。查看When should I use the new keyword in C++? -
Foo::new_num返回的是什么? -
这是一种不好的做法——一方面,像
foo(new Bar, new Baz);这样的函数调用几乎不可能使异常安全(例如,如果先执行new Bar,然后再执行Baz构造函数抛出一个异常,因此foo()永远不会被调用,你已经泄漏了一个Bar对象,因为没有人持有指向Bar的指针,可以delete它)
标签: c++ function memory dynamic-memory-allocation new-operator