it-swarm.cn

为什么用C ++编码时不建议使用指针?

我从某处了解到,在使用C++时,建议不要使用指针。在使用C++时,为什么指针这么不好?对于习惯使用指针的C程序员,C++中更好的替代方法是什么?

45
Joshua Partogi

我认为它们意味着您应该使用 智能指针 而不是常规指针。

在计算机科学中,智能指针是一种抽象的数据类型,它在提供附加功能(例如自动垃圾收集或边界检查)的同时模拟指针。这些附加功能旨在减少因滥用指针而导致的错误,同时保持效率。智能指针通常会跟踪它们指向的对象,以进行内存管理。

指针的滥用是错误的主要来源:使用指针编写的程序必须执行的常量分配,释放和引用会带来内存泄漏的风险。智能指针试图通过使资源自动分配来防止内存泄漏:当对象的指针(或一系列指针中的最后一个)被破坏时(例如,由于超出范围,则指向的对象也被破坏)。

在C++中,重点将放在垃圾回收和防止内存泄漏(仅举两个)上。指针是语言的基本组成部分,因此除了最普通的程序之外,几乎不使用指针是不可能的。

58
jmq

由于我是发表争论的人 “不要使用f * cking指针” 我觉得我应该在这里发表评论。

首先,作为争论,它显然代表了一种极端的观点。 are绝对是(原始)指针的合法使用。但是我(和许多专业的C++程序员)坚持认为,这种情况极为罕见。但是,我们真正的意思是:

第一:

原始指针在任何情况下都不得拥有内存。

在这里,“自己的内存”本质上是指在某个时刻在该指针上调用了delete(但比这更笼统)。 此语句可以放心地作为绝对值。only例外是在实现自己的智能指针(或其他内存管理)时战略)。即使在那儿,您通常也应该still在低级使用智能指针。

这样做的理由很简单:拥有内存的原始指针会引入错误源。这些错误在现有软件中是多产的:内存泄漏和双重删除-两者都是资源所有权不明确的直接结果(但方向相反)。

通过简单地使用智能指针而不是原始指针,可以几乎完全免费地解决此问题(注意:当然,这仍然需要进行思考;共享指针can会导致循环,并因此再次导致内存泄漏-但这很容易避免)。

第二:

在C++中,大多数指针的使用都是不必要的。

与其他语言不同,C++对值语义有很强的支持,并且根本不需要指针的间接调用。尚未立即意识到-历史上,C++的发明是为了简化C语言中的对象定向,并且严重依赖于构建通过指针连接的对象图。但是在现代C++中,这种范例很少是最佳选择,并且现代C++习惯用法通常根本不需要指针。它们对values而不是指针进行操作。

不幸的是,此消息仍未在C++用户社区中流行。结果,大多数编写的C++代码仍然充满了多余的指针,这使代码变得复杂,缓慢,错误/不可靠。

对于了解现代C++的人来说,很明显,您很少需要any指针(无论是智能指针还是原始指针;除非将它们用作迭代器)。生成的代码更短,更简单,更易读,通常更高效,更可靠。

97
Konrad Rudolph

仅仅是因为有一些可用的抽象,这些抽象隐藏了使用指针的更多气质方面,例如访问原始内存和在分配后进行清理。使用智能指针,容器类和RAII之类的设计模式,就可以减少使用原始指针的需要。也就是说,就像任何抽象一样,您应该先了解它们的实际工作方式,然后再超越它们。

15
Ed S.

相对而言,C的心态是“遇到问题了?使用指针”。您甚至可以在C++早期使用成员指针的情况下,在C字符串,函数指针,指针作为迭代器,指针对指针,空指针中看到这一点。

但是在C++中,您可以将值用于许多或所有这些任务。需要功能抽象吗? std::function。这是一个功能的价值。 std::string?这是一个值,那是一个字符串。您可以在C++上看到类似的方法。这使得对人类和编译器的代码分析变得非常容易。

11
DeadMG

原因之一是指针的应用范围太广。它们可用于在容器上进行迭代,避免在传递给函数时复制大型对象,非平凡的生命周期管理,访问内存中的随机位置等。一旦将它们用于某个目的,它们的其他功能也将可用立即立意独立。

选择特定用途的工具可使代码更简单,意图更清晰-迭代器,生命周期管理的智能指针等。

10
maxim1000

除了已经列出的原因之外,还有一个显而易见的原因:更好的优化。在使用指针算术的前提下,别名分析太复杂了,而引用则暗示了一个优化器,因此,如果仅使用引用,则可能进行更深入的别名分析。

3
SK-logic

除了@jmquigley指出的内存泄漏风险外,还可以考虑使用指针和指针算术,因为指针可以指向内存中的任何地方导致“难以发现错误”和“安全漏洞”。

这就是为什么它们几乎被C#和Java弃用的原因。

2
k3b