本文介绍了是否有任何有效的用例可以在现代 C++ 中使用 new 和 delete、原始指针或 c 样式数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个值得注意的视频(停止教授 C)关于在教授 C++ 语言时要采取的范式改变.

还有一篇著名的博文

我有一个梦想......

我梦想所谓的 C++ 课程/课程/课程将停止教授(要求)他们的学生使用:...

I'm dreaming of so called C++ courses/classes/curriculae will stop teaching (requiring) their students to use: ...

由于 C++11 作为既定标准,我们有了 动态内存管理 设施又名智能指针.
即使从早期的标准,我们也有 C++ 标准 容器库 作为原始数组的良好替代品(使用 new T[] 分配)(特别是使用 std::string 而不是 c 风格的 NUL 终止字符数组).

Since C++11 as established standard we have the Dynamic memory management facilities aka smart pointers.
Even from earlier standards we have the c++ standard Containers library as a good replacement for raw arrays (allocated with new T[]) (notably usage of std::string instead of c-style NUL terminated character arrays).

问题粗体:

撇开放置new覆盖,是否有任何有效的用例无法使用智能指针或标准容器实现,而只能使用newdelete直接(当然除了实现这样的容器/智能指针类)?

Let aside the placement new override, is there any valid use case that can't be achieved using smart pointers or standard containers but only using new and delete directly (besides implementation of such container/smart pointer classes of course)?

有时传闻(例如这里此处) 使用 newdelete 手动操作可以更高效"某些情况.这些实际上是什么?这些边缘情况难道不需要像标准容器或智能指针一样跟踪分配吗?

It's sometimes rumored (like here or here) that using new and delete handrolled can be "more efficient" for certain cases. Which are these actually? Don't these edge cases need to keep track of the allocations the same way as standard containers or smart pointers need to do?

对于原始 c 风格的固定大小数组几乎相同:现在有 std::array,它允许各种赋值、复制、引用等,如预期的那样轻松且语法一致每个人.是否有任何用例可以选择 T myArray[N]; c 样式数组而不是 std::arraymyArray;?

Almost the same for raw c-style fixed size arrays: There is std::array nowadays, which allows all kinds of assignment, copying, referencing, etc. easily and syntactically consistent as expected by everyone. Are there any use cases to choose a T myArray[N]; c-style array in preference of std::array<T,N> myArray;?

关于与第 3 方图书馆的互动:

Regarding interaction with 3rd party libraries:

假设第 3 方库返回使用 new 分配的原始指针,例如

Assumed a 3rd party library returns raw pointers allocated with new like

MyType* LibApi::CreateNewType() {
    return new MyType(someParams);
}

您始终可以将其包装到智能指针以确保调用 delete:

you can always wrap that to a smart pointer to ensure that delete is called:

std::unique_ptr<MyType> foo = LibApi::CreateNewType();

即使 API 要求你调用他们的遗留函数来释放资源,比如

even if the API requires you to call their legacy function to free the resource like

void LibApi::FreeMyType(MyType* foo);

你仍然可以提供一个删除器功能:

you still can provide a deleter function:

std::unique_ptr<MyType, LibApi::FreeMyType> foo = LibApi::CreateNewType();


我对有效的每天"用例特别感兴趣,这与学术/教育目的要求和限制形成对比,上述要求和限制未涵盖这些标准设施.
newdelete 可用于内存管理/垃圾收集器框架或标准容器实现中,这是不可能的.


I'm especially interested in valid "every day" use cases in contrast to academic/educational purpose requirements and restrictions, which aren't covered by the mentioned standard facilities.
That new and delete may be used in memory management / garbage collector frameworks or standard container implementation is out of question.

...问这个问题是提供一种替代方法,而不是任何(家庭作业)问题,这些问题仅限于使用标题中提到的任何结构,但是关于生产就绪代码的严肃问题.

... to ask this question is to give an alternative approach vs any (homework) questions, which are restricted to use any of the constructs mentioned in the title, but serious questions about production ready code.

这些通常被称为内存管理的基础,这是 IMO 公然错误/误解为适合初学者讲座和任务.

These are often referred to as the basics of memory management, which is IMO blatantly wrong/misunderstood as suitable for beginners lectures and tasks.

推荐答案

当所有权不应该是本地的.

When ownership should not be local.

举个例子,指针容器可能不希望其中的指针的所有权驻留在指针本身中.如果您尝试编写具有前向唯一 ptr 的链表,则在销毁时您很容易炸毁堆栈.

As an example, a pointer container may not want ownership over the pointers in it to reside in the pointers themselves. If you try to write a linked list with forward unique ptrs, at destruction time you can easily blow the stack.

类似vector 的拥有指针的容器可能更适合在容器或子容器级别存储删除操作,而不是在元素级别.

A vector-like container of owning pointers may be better suited to storing delete operation at the container or subcontainer level, and not at the element level.

在这些和类似的情况下,您可以像智能指针一样包装所有权,但您是在更高的级别上进行的.许多数据结构(图等)可能有类似的问题,所有权正确地位于比指针所在位置更高的位置,并且它们可能不会直接映射到现有的容器概念.

In those and similar cases, you wrap ownership like a smart pointer does, but you do it at a higher level. Many data structures (graphs, etc) may have similar issues, where ownership properly resides at a higher point than where the pointers are, and they may not map directly to an existing container concept.

在某些情况下,从数据结构的其余部分中分离出容器所有权可能很容易.在其他情况下可能不会.

In some cases it may be easy to factor out the container-ownership from the rest of the data structure. In others it may not.

有时您有非常复杂的非本地非引用计数生命周期.在这些情况下,没有明智的地方可以放置所有权指针.

Sometimes you have insanely complex non-local non-reference counted lifetimes. There is no sane spot to put the ownership pointer in those cases.

在这里确定正确性很难,但并非不可能.存在正确且具有如此复杂所有权语义的程序.

Determining correctness here is hard, but not impossible. Programs that are correct and have such complex ownership semantics exist.

所有这些都是极端情况,很少有程序员会在职业生涯中多次遇到它们.

All of these are corner cases, and few programmers should run into them more than a handful of times in a career.

这篇关于是否有任何有效的用例可以在现代 C++ 中使用 new 和 delete、原始指针或 c 样式数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 12:56