c++ - 在 C++ 中,对象和指向对象的指针有什么区别?

标签 c++ pointers object

在java和objective-c中,表示对象的变量一般是指向该对象的指针。但是,在 C++ 中,非指针类型保存对象似乎很常见。两者有什么区别?

如果我将一个结构作为参数传递给一个函数,我相信我是按值传递的,这意味着我实际上是在内存中创建一个新的结构,并且在它传递给的函数内部对该结构的更改不会影响函数外部的“源”结构。但是,如果我将一个指针传递给一个结构,仍然只有一个原始结构,并且指针引用的结构的更改将对任何知道该结构的代码可见。我有这个权利吗?

那么,对象有什么区别吗?当我将非指针对象传递给函数时,是否复制了整个对象?

最佳答案

正如你所说。

当您按值传递对象时,将调用其复制构造函数 以生成将在函数内部使用的此类对象的新实例。对此类新对象所做的更改不会反射(reflect)到原始对象1

与结构一样,默认复制构造函数只是对原始对象进行浅拷贝 - 即,它的字段被复制2 到新实例;在许多情况下,这是不可取的(例如,如果对象包装了一个指针/另一个资源),因此有些类会重新定义复制构造函数或完全禁用它。最后这些类的对象只能通过指针或引用传递。

如果对象大于指针(在大小上),或者通常如果它们的复制构造函数不“便宜”,则按值传递对象的成本可能很高。另一方面,与指针相比,按值传递具有不必指定指针所有权、让被调用者对对象做任何想做的事情等通常的优点。

请注意,按值传递对象会破坏多态性。这是因为按值接收对象的函数接收静态类型对象,具有精确的大小和类型,因此任何传递派生类对象的尝试都将导致对象切片(调用基类的复制构造函数,即默认情况下只复制基类中可用的字段。

这就是为什么传递对象的首选方法通常是通过 const 引用的原因。这产生了几个优点:

  • 不涉及拷贝;被调用者将看到的对象将与调用时指定的对象完全相同;
  • 由于 const 限定符,不能对原始对象进行任何更改;
  • 但是,如果被调用者需要更改对象的拷贝,它仍然可以根据引用自己构造一个拷贝;
  • 没有笨拙的指针语法;
  • 保留了多态性,因为在幕后我们实际上传递了一个指针;
  • 对对象所有权没有太大疑问:关于引用的一般规则是它们由调用者拥有。

  1. 就对象的“原始字段”而言;当然,如果原始对象和拷贝继续共享指向同一资源的指针/句柄,对其中一个的一些修改可能会影响另一个。

  2. 原始类型(以及一般的 POD)按位复制,而非 POD 类型调用复制构造函数。

关于c++ - 在 C++ 中,对象和指向对象的指针有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5372707/

相关文章:

c++ - 模板实例化深度超过最大值 - 如何停止特定情况?

c++ - 为什么模板参数推导/替换在这里失败?

c++ - 错误 : linker command failed with exit code 1 (use -v to see invocation) : on Macbook

c - 访问由双指针创建的数组中的维度之外

c - 带有数组的指针函数

c - 在函数中通过指向多维数组的指针分配指针

Javascript 对象无法与 native javascript 方法(如 match()、替换等)一起使用

c# - 如何在 Windows 中获取和设置系统音量

javascript - 即使属性存在,js 对象也会返回未定义

java - 单个类是否比 6 个更简单更好?