重点是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-type 表达式进行实例化。在接近 C++ 时,这本身就是一种非常无益的心态:
C++ 中的关键区别在于对象lifetime,或“存储类”。这可以是以下之一:自动(作用域)、静态(永久)或动态(手动)。全局变量具有静态生命周期。绝大多数变量(在本地范围内声明为Foo x;)具有自动生命周期。我们使用new 表达式仅用于动态 存储。当从另一种 OO 语言转向 C++ 时,最重要的一点是大多数对象只需要具有自动生命周期,因此无需担心。
所以第一个认识应该是“C++很少需要动态存储”。我觉得这可能是 OP 问题的一部分。这个问题可能更好地表述为“动态分配对象真的是个坏主意吗?”。只有在你决定你真的需要动态存储之后,我们才会讨论你是否应该经常说new和delete,或者是否有更好的替代方案,是我原来回答的重点。