在C ++中,对象和指向对象的指针有什么区别? [英] in C++, what's the difference between an object and a pointer to an object?

查看:240
本文介绍了在C ++中,对象和指向对象的指针有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在java和Objective-c中,代表对象的变量通常是指向该对象的指针.但是,似乎在C ++中,让非指针类型保存对象是很常见的.两者有什么区别?

In java and objective-c, a variable representing an object is generally a pointer to that object. However, it seems that in C++, it's common to have non-pointer types hold objects. What's the difference between the two?

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

If I pass a struct as an argument to a function, I believe I'm passing by value, meaning I'm actually creating a new struct in memory, and changes to that struct inside the function its passed to won't affect the "source" struct outside the function. However, if I pass a pointer to a struct, there's still only one original struct, and changes to the struct referenced by the pointer will be visible to any code which is aware of this struct. Do I have that right?

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

So, is there any difference with objects? When I pass a non-pointer object to a function, does the entire object get copied?

推荐答案

与您所说的完全一样.

当您按值传递对象时,将调用其 copy构造函数来生成此类对象的新实例,该实例将在函数内部使用.对此类新对象所做的更改不会反映到原始对象 1 .

When you pass an object by value, its copy constructor is invoked to produce a new instance of such object that will be used inside the function. The changes done to such new object won't be reflected to the original one1.

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

As with structures, the default copy constructor just does a shallow copy of the original object - i.e., its fields are copied2 to the new instance; in many cases this is not desirable (e.g. if the object wraps a pointer/another resource), so there are classes which redefine the copy constructor or disable it completely. Objects of these last classes can only be passed by pointer or reference.

如果值大于指针(按大小),则按值传递对象可能会很昂贵,或者通常,如果其复制构造函数不是便宜"的对象,则传递代价会很高.另一方面,与指针相比,按值传递具有通常的优点,即不必指定指针所有权,让被调用者对对象执行任何操作,等等.

Passing objects by value can be costly if they are bigger than a pointer (in size) or in general if their copy constructor isn't "cheap". On the other hand, in comparison to pointers, the pass-by-value yields the usual advantages of not having to specify the pointer ownership, letting the callee do whatever it wants with the object, etc.

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

Notice that passing an object by value kills the polymorphism. This because a function receiving an object by value receives a statically typed object, with a precise size and type, so any attempt to pass an object of a derived class will result in object slicing (the copy constructor for the base class is called, that by default just copies the fields that are available in the base class).

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

This is the reason why often the preferred method of passing objects is by const reference. This yields several advantages:

  • 不涉及副本;被呼叫者将看到的对象将恰好是呼叫时指定的对象;
  • 由于const限定符,无法对原始对象进行任何更改;
  • 但是,如果被调用方需要更改对象的副本,它仍然可以从引用中自己构造一个副本;
  • 没有笨拙的指针语法;
  • 多态性得以保留,因为我们实际上是在幕后传递了一个指针;
  • 对对象所有权没有很大的怀疑:关于引用的一般规则是它们由调用者拥有.
  • no copies involved; the object that the callee will see will be exactly the one specified at the moment of the call;
  • no changes to the original object can be made, thanks to the const qualifier;
  • if however the callee needs to change a copy of the object, it can still construct a copy by itself from the reference;
  • no awkward pointer syntax;
  • polymorphism preserved, since behind the scenes we're actually passing a pointer;
  • no big doubts about object ownership: the general rule about references is that they are owned by the caller.
  1. 就对象的原始字段"而言;自然,如果原始对象和副本继续共享指向同一资源的指针/句柄,则对一个资源的某些修改可能会影响另一个资源.

  1. As far as the "raw fields" of the object are concerned; naturally if the original object and the copy continue to share a pointer/handle to the same resource some modifications to one may affect the other.

原始类型(通常是POD)按位复制,而非POD类型则调用复制构造函数.

Primitive types (and in general PODs) are copied bitwise, while the copy constructor is called for non-POD types.

这篇关于在C ++中,对象和指向对象的指针有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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