您将如何替换“新”? 关键词?

发布于 2024-08-01 22:53:59 字数 265 浏览 7 评论 0原文

我很久以前发现了一篇文章(我在 ATM 上找不到它),其中阐述了 C++ 中 new 关键字不好的原因。 我不记得所有的原因,但我记得最清楚的两个是你必须将new与delete匹配,new[]与delete[]匹配,并且你不能像与malloc一样使用#define与new。

我正在设计一种语言,所以我想问你如何改变 C++ 语言,这样新的语言就更友好了。 请随意陈述新文章和文章的问题。 我希望我能找到该文章的链接,但我记得它很长,并且是由(IIRC)一所知名学校的一位教授撰写的。

There was an article i found long ago (i cant find it ATM) which states reasons why the new keyword in C++ is bad. I cant remember all of the reasons but the two i remember most is you must match new with delete, new[] with delete[] and you cannot use #define with new as you could with malloc.

I am designing a language so i like to ask how would you change the C++ language so new is more friendly. Feel free to state problems with new and articles. I wish i can find the article link but i remember it was long and was written by a professor at (IIRC) a known school.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

橘和柠 2024-08-08 22:53:59

C++ 具有单独的 new 运算符(或 C malloc )的原因主要是为了可以创建其生命周期超出创建它们的函数范围的对象。

如果您有尾部调用消除和延续,您就不会关心 - 对象都可以在堆栈上创建并且具有无限的范围 - 对象可以存在,直到您调用与超出范围并被破坏的对象相对应的延续。 然后,您可能需要一些东西来进行垃圾收集或以其他方式压缩堆栈,以便它不会充满不再需要的对象(ChickenScheme 和 TinyOS 2 是两个不同的示例,它们在运行时或编译时;鸡方案不允许 RAII,TinyOS 不允许真正的动态分配),尽管对于大量代码,这样的方案与 RAII 没有太大不同,可以选择更改顺序物体被毁坏。

The reason that C++ has a separate new operator ( or C malloc ) is primarily so that objects can be created whose lifetimes exceed the scope of the function which creates them.

If you had tail call elimination and continuations, you wouldn't care - the objects could all be created on the stack and have unlimited extent - an object can exist until you call the continuation that corresponds to the object going out of scope and being destructed. You might then need something to garbage collect or otherwise compress the stack so it doesn't become full of no-longer required objects ( Chicken Scheme and TinyOS 2 are two different examples for giving the effect of dynamic memory without dynamic memory at either runtime or compile time; Chicken Scheme doesn't allow for RAII and TinyOS doesn't allow for true dynamic allocation ), though for a large amount of code such a scheme wouldn't be vastly different to RAII with the facility to chose to change the order the objects are destructed.

暗喜 2024-08-08 22:53:59

问题匹配 new、delete、new[]、delete[]

并不是什么大问题。
您应该将内存分配包装在一个类中,这样这不会真正影响普通用户。 单个对象可以用智能指针包装。 虽然数组可以用 std::Vector<> 表示,但也可以用 std::Vector<> 来表示。

不能像使用 malloc 那样将 #define 与 new 一起使用。

像这样搞乱 malloc 的原因是在您的应用程序和标准内存管理层之间引入您自己的内存管理层。 这是因为在 C 中,不允许您编写自己的 malloc 版本。 在 C++ 中,编写自己的 new 版本是相当合法的,这使得这个技巧变得不必要。

Problem match new, delete, new[], delete[]

Not really a big deal.
You should be wrapping memory allocation inside a class so this does not really affect normal users. A single obejct can be wrapped with a smart pointer. While an array can be represented by std::Vector<>

cannot use #define with new as you could with malloc.

The reason to mess with malloc like this was to introduce your own memory management layer between your app and the standard memory management layer. This is because in C you were not allowed to write your own version of malloc. In C++ it is quite legal to write your own version of the new which makes this trick unnecessary.

无人接听 2024-08-08 22:53:59

我会给它 C# 中的 new 语义(或多或少):

  1. 为对象分配内存。
  2. 通过将成员变量设置为其默认值(通常为 0 为值,null 为引用)来初始化内存。
  3. 初始化对象的动态绑定机制(C++ 中的 vtable,托管 VM 的类型 def 表)。
  4. 调用构造函数,此时虚拟调用将按预期工作。
  5. 对于没有垃圾收集的语言(此时对于新语言来说),从调用中返回一个 smart_ptr 或类似的值。

另外,将所有对象设置为值类型或引用类型,这样您就不必保留显式的 smart_ptr。 只允许 new 为引用类型进行堆分配,并确保它包含正确调用析构函数的信息。 对于值类型,new 从堆栈中调用内存上的构造函数。

I'd give it the semantics of new in C# (more or less):

  1. Allocates memory for the object.
  2. Initializes the memory by setting the member variables to their default values (generally 0 for values, null for references).
  3. Initializes the object's dynamic binding mechanism (vtables in C++, type def tables for managed VMs).
  4. Calls the constructor, at which point virtual calls work as expected.
  5. For a language without garbage collection (eww for a new language at this point), return a smart_ptr or similar from the call.

Also, make all objects either value types or reference types, so you don't have to keep an explicit smart_ptr. Only allow new to heap-allocate for reference types, and make sure it contains information to properly call the destructor. For value types, new calls the constructor on memory from the stack.

や三分注定 2024-08-08 22:53:59

使用垃圾收集,这样您就不需要将新的与任何东西相匹配。

Use Garbage Collection so that you never need to match new with anything.

迷离° 2024-08-08 22:53:59

通过使用STL容器类和各种boost:smart_ptrs,几乎不需要在C++代码中显式调用new或delete。

您可能需要调用 new 的几个地方(例如,初始化智能指针)使用命名构造函数惯用法来返回包装在 例如 boost:shared_ptr.

但是 C++ 和 STL 非常努力地允许您将大多数对象视为值对象,因此您可以构造对象而不是指针并直接使用它们。

考虑到这一切,几乎没有必要替换 new 运算符——而且这样做会引入许多问题,无论是需要垃圾收集器,还是减少 C++ 为程序员提供的精细低级控制。

By using the STL container classes and the various boost:smart_ptrs, there's little need to ever explicitly call new or delete in your C++ code.

The few places you might need to call new (e.g, to initialize a smart pointer) use the Named Constructor Idiom to return your class type pointer wrapped in, e.g., a boost:shared_ptr.

But C++ and the STL work very very hard to allow you to treat most objects as value objects, so you can construct objects rather than pointers and just use them.

Given all this, there's little need to replace the new operator -- and doing so would introduce a host of problems, whether by requiring a garbage collector, or by reducing the fine low-level control C++ offers programmers.

眼泪都笑了 2024-08-08 22:53:59

如果您的new语言被垃圾收集,您可以避免使用new关键字。 这就是 Python 所做的事情(而 Lisp 几乎 5 年前就这么做了!)。 另请参阅 此处 Peter Norvig 针对类似问题提供的答案。 (没有“消息”就是好消息吗?)

If your new language is garbage collected, you can avoid the new keyword. Thats what Python did (and Lisp did almost 5 decades ago!). Also see an answer provided by Peter Norvig for a similar question here. (Is no "news" good news?)

飘落散花 2024-08-08 22:53:59

有时您想用工厂替换构造函数。 这是众所周知的重构。 用工厂方法替换构造函数。 那么也许这就是这篇文章的意思?

顺便说一句,您经常会看到对 new 的直接调用被替换为工厂方法

Unity 等 DI 框架将这一概念提升到了另一个层次。 正如您在以下 C# 代码中所看到的,没有应用“new”来创建 IMyClass 接口:

IUnityContainer myContainer = new UnityContainer();
myContainer.RegisterType<IMyClass, SomeClass>();
IMyClass thing = myContainer.Resolve<IMyClass>();

Sometimes you want to replace the constructor with a factory. This is a well known refactoring. Replace Constructor With Factory Method. So perhaps this is what the article meant?

Incidentally you will often see straight calls to new being replaced with a Factory Method.

DI frameworks such as Unity take this concept to another level. As you can see in the following C# code, there is no "new" applied to create the IMyClass interface:

IUnityContainer myContainer = new UnityContainer();
myContainer.RegisterType<IMyClass, SomeClass>();
IMyClass thing = myContainer.Resolve<IMyClass>();
栀子花开つ 2024-08-08 22:53:59

我看不出有任何理由用其他东西替换 new 关键字(并且 C++ 委员会似乎同意我的观点)。 它很清晰,并且做了它应该做的事情。 您可以在类中重写operator new,无需使用定义。

要消除 new[]/delete[] 问题,您可以使用 std::vector

如果你想使用智能指针,你可以使用它,但我想控制何时使用智能指针。 这就是为什么我喜欢它在 C++ 中的工作方式 — 具有控制低级细节的能力的高级行为。

I cannot see any reason to replace the new keyword with something else (and seems to be that C++ committee agree with me). It is clear and makes what it should. You could override operator new in your class, no need to use defines.

To eliminate new[]/delete[] problem you could use std::vector.

If you want to use smart pointer you could use it, but I want to control when smart pointer will be used. That's why I like how it works in C++ — high level behavior with ability to control low level details.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文