为什么使用“新”是个坏主意? [英] Why is it a bad idea to use 'new'?

查看:148
本文介绍了为什么使用“新”是个坏主意?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


可能重复:

new ?


在C ++中使用'new'实例化一个类真的不好吗? 在此找到



我认为使用原始指针是不明智的,但为什么有一个'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); //等于p2,但更好






更新:我想我可能只解决了OP的一半关注。许多来自其他语言的人似乎都受到以下印象:任何对象必须用 new 类型表达式实例化。这在处理C ++时本身是一种非常无用的心态:



C ++中关键的区别是对象生命期 。这可以是以下之一:自动 (scoped),静态(永久)或动态全局变量具有静态寿命。绝大多数所有变量(在本地作用域内被声明为 Foo x; )具有自动生命周期。只有动态存储,我们使用 new 表达式。从另一个OO语言到C ++的时候,最重要的事情是,大多数对象只需要有自动生命周期,因此从来没有什么需要担心的。



因此,第一个实现应该是C ++很少需要动态存储。我觉得这可能是OP的问题的一部分。问题可能被更好地表述为动态分配对象是一个很糟糕的主意吗?只有之后你决定你真的需要动态存储,我们才能讨论你是否应该说 new delete 很多,或者如果有更好的选择,这是我原来答案的要点。


Possible Duplicate:
In C++, why should new be used as little as possible?

Is it really a bad idea to use 'new' in instantiating a class in C++? Found here.

I get that using raw pointers is ill-advised, but why have a 'new' keyword at all when it's such bad practice? Or is it?

解决方案

The point is that new, much like a pregnancy, creates a resource that is managed manually (i.e. by you), and as such it comes with responsibility.

C++ is a language for library writing, and any time you see a responsibility, the "C++" approach is to write a library element that handles this, and only this, responsibility. For dynamic memory allocation, those library components already exist and are summarily referred to as "smart pointers"; you'll want to look at std::unique_ptr and std::shared_ptr (or their TR1 or Boost equivalents).

While writing those single-responsibility building blocks, you will indeed need to say new and delete. But you do that once, and you think about it carefully and make sure you provide the correct copy, assignment and destruction semantics. (From the point of exception safety, single responsibility is crucial, since dealing with more than one single resource at a time is horribly unscalable.)

Once you have everything factored into suitable building blocks, you compose those blocks into bigger and bigger systems of code, but at that point you don't need to exercise any manual responsibility any more, since the building blocks already do this for you.

Since the standard library offers resource managing classes for the vast majority of use cases (dynamic arrays, smart pointers, file handles, strings), the point is that a well-factored and crafted C++ project should have very little need for any sort of manual resource management, which includes the use of new. All your handler objects are either automatic (scoped), or members of other classes whose instances are in turn scoped or managed by someone.

With this in mind, the only time you should be saying new is when you create a new resource-managing object; although even then that's not always necessary:

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


Update: I think I may have addressed only half the OP's concerns. Many people coming from other languages seem to be under the impression that any object must be instantiated with a new-type expression. This is in itself a very unhelpful mindset when approaching C++:

The crucial distinction in C++ is that of object lifetime, or "storage class". This can be one of: automatic (scoped), static (permanent), or dynamic (manual). Global variables have static lifetime. The vast majority of all variables (which are declared as Foo x; inside a local scope) have automatic lifetime. It is only for dynamic storage that we use a new expression. The most important thing to realize when coming to C++ from another OO language is that most objects only ever need to have automatic lifetime, and thus there is never anything to worry about.

So the first realization should be that "C++ rarely needs dynamic storage". I feel that this may have been part of the OP's question. The question may have been better phrased as "is it a really bad idea to allocate objects dynamically?". It is only after you decide that you really need dynamic storage that we get to the discussion proper of whether you should be saying new and delete a lot, or if there are preferable alternatives, which is the point of my original answer.

这篇关于为什么使用“新”是个坏主意?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆