为什么使用'新'是一个坏主意?
可能重复:
在C ++中,为什么new
应尽可能少用?
在C ++中使用'new'实例化一个类真的是一个坏主意吗? 在这里找到。
我明白,使用原始指针是不明智的,但为什么有一个'新'关键字在所有这些不好的做法? 或者是?
重点是new
,就像怀孕一样,创建一个手动管理的资源(即由你来管理),因此它带有责任。
C ++是图书馆写作的语言,每当你看到责任时,“C ++”方法就是编写一个处理这个问题的库元素,只有这个责任。 对于动态内存分配,这些库组件已经存在并被简称为“智能指针”; 你会想看看std::unique_ptr
和std::shared_ptr
(或者它们的TR1或Boost等价物)。
在编写这些单一责任构建块时,您确实需要说new
和delete
。 但是你一次就这样做,并仔细考虑,并确保提供正确的副本,分配和销毁语义。 (从异常安全的角度来看,单一责任是至关重要的,因为一次处理多个单一资源是非常难以实现的。)
一旦你将所有东西都分解成合适的构建块,就可以将这些块组合成更大更大的代码系统,但此时您不需要再执行任何手动任务,因为构建块已经为您执行了此操作。
由于标准库为大多数用例(动态数组,智能指针,文件句柄,字符串)提供了资源管理类,因此问题在于,一个良好分解和制作的C ++项目应该几乎不需要任何手册资源管理,其中包括使用new
。 所有的处理程序对象都是自动的(作用域),或者其他类的成员,而这些类的实例又由某个作用域或管理。
考虑到这一点,你应该说new
的唯一的时候是当你创建一个新的资源管理对象; 虽然即使这样也并非总是必要的:
std::unique_ptr<Foo> p1(new Foo(1, 'a', -2.5)); // unique pointer
std::shared_ptr<Foo> p2(new Foo(1, 'a', -2.5)); // shared pointer
auto p3 = std::make_shared<Foo>(1, 'a', -2.5); // equivalent to p2, but better
更新:我想我可能只解决了OP的一半问题。 很多来自其他语言的人似乎都觉得任何对象都必须用new
表达式来实例化。 在接近C ++时,这本身就是一个无益的心态:
C ++的关键区别在于对象生命周期或“存储类”。 这可以是以下之一:自动(范围),静态(永久)或动态(手动)。 全局变量具有静态生命期。 绝大多数变量(在本地范围内声明为Foo x;
)都具有自动生命期。 只有动态存储才能使用new
表达式。 从另一种OO语言来到C ++时最重要的事情是,大多数对象只需要自动生命周期,因此绝对不需要担心。
所以第一个认识应该是“C ++很少需要动态存储”。 我觉得这可能是OP问题的一部分。 这个问题可能被更好地表述为“动态地分配对象是一个非常糟糕的主意?”。 只有在你决定真的需要动态存储之后,我们才能讨论你是否应该说new
并且delete
很多,或者如果有更好的选择,这是我原来的答案的要点。
尽可能避免new
,意味着很多好处,例如:
首先也是最重要的,你也避免delete
语句。尽管智能指针可以帮助你。 所以这不是那个强项。
您避免三规则(在C ++ 03中)或五规则(在C ++ 11中)。 如果你在设计一个类时使用new
,也就是说,当你的类在内部管理原始内存时,你可能必须考虑这个规则。
当你不使用new
时候,很容易实现异常安全的代码。 否则,你必须面对很多问题,使你的代码异常安全。
不必要地使用new
手段意味着您引发问题。 我已经看到,当一个没有经验的程序员使用new
,他有更好的选择,比如使用标准容器和算法。 标准容器的使用避免了显式使用new
问题带来的大多数问题。
这并不坏,但是你用new
分配的所有东西都必须用delete
来释放。 这并不总是微不足道的,尤其是在考虑到异常情况时。 我认为那是这篇文章的意思。