C++ 在C++;,什么';对象和指向对象的指针之间的区别是什么?

C++ 在C++;,什么';对象和指向对象的指针之间的区别是什么?,c++,pointers,object,C++,Pointers,Object,在java和objective-c中,表示对象的变量通常是指向该对象的指针。但是,在C++中,非指针类型保存对象是常见的。这两者有什么区别 如果我将一个结构作为参数传递给一个函数,我相信我是通过值传递的,这意味着我实际上是在内存中创建一个新的结构,并且在传递给它的函数内部对该结构的更改不会影响函数外部的“源”结构。但是,如果我将指针传递给一个结构,则仍然只有一个原始结构,并且指针引用的结构的更改对于任何知道该结构的代码都是可见的。我有这个权利吗 那么,物体有什么区别吗?当我将非指针对象传递给函数

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

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


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

第二段和第三段中的问题的答案都是“是”。更具体地说,如果按值将对象传递给函数,函数将收到该对象的副本(由复制构造函数创建)。

当按值将对象传递给函数时,它将通过其类的复制构造函数进行复制。如果尚未定义复制构造函数,编译器将提供一个默认构造函数(除非您采取特殊步骤避免),这相当于手动复制成员

首选的方法通常是传递常量引用,而不是指针或对象本身

(您可能希望知道,实际上,<代码>结构> <代码>只是一个<代码>类< /CU>,默认情况下,它的成员是代码>公用< /代码>;特别是,结构也可以有用户定义的复制构造函数。结构不一定是纯惰性数据。C++中的

< P>,变量是它所代表的变量。它是内存中的实际对象,位于实际位置

但是,您可以选择让这样的变量表示指针,在这种情况下,它会说“嘿,我是我,我指向那里!您想要的对象不在这里,它在那里。是的,那里!继续,到达那里!”

除非您显式地使用C++的“引用类型”(我怀疑您不是),否则您传递的所有参数都是按值传递的。

您有这个权利

事实上,这就是它的工作原理。指针存储变量的内存地址

当您将函数的指针(指向对象)作为参数传递时,这意味着该函数将通过其内存地址访问该对象,而不是在堆栈上创建新对象


查看有关指针的更多信息。

完全如您所说

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

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

如果对象大于指针(大小),或者如果复制构造函数不“便宜”,则按值传递对象可能代价高昂。另一方面,与指针相比,pass-by值具有不必指定指针所有权、允许被调用方对对象执行任何操作等常见优点

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

这就是为什么传递对象的首选方法通常是通过
const
reference。这有几个优点:

  • 不涉及副本;被调用方将看到的对象正好是调用时指定的对象
  • 由于
    const
    限定符,无法对原始对象进行任何更改
  • 但是,如果被调用方需要更改对象的副本,它仍然可以从引用中自行构造副本
  • 没有笨拙的指针语法
  • 多态性被保留,因为在幕后我们实际上在传递一个指针
  • 关于对象所有权没有什么大的疑问:关于引用的一般规则是它们属于调用方

  • 就对象的“原始场”而言;当然,如果原始对象和副本继续共享指向同一资源的指针/句柄,则对其中一个对象的某些修改可能会影响另一个对象

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


  • 区别主要与对象在内存中的分配位置有关。例如:

    int main() {
        MyObject x;   //allocates space for an instance of MyObject on the stack
        MyObject* y;  //allocates space for a pointer on the stack
        MyObject* z = new MyObject();  //allocates space for a pointer on the 
                                       //stack and an object instance in the heap and
                                       //sets the pointer to point to the new instance
        MyObject* a = &x;  //allocates space for a pointer on the stack and 
                           //makes it point to 'x'
        ...
    }
    
    int someFunc(MyObject byValue, MyObject* byReference) {
       //the 'byValue' parameter will be passed by creating a copy of the 
       //entire source object on the stack (can be quite expensive for 
       //complex object types)
    
       //the 'byReference' parameter will be passed by creating a 
       //copy of the source pointer on the stack and setting it to 
       //point to the source object in memory
    }
    
    • 指针存储内存地址
    • 变量存储一个值
    例:


    实际上,如果这些VAR是全局的,在大多数平台上它们将不被放置在堆栈上,而是在专用于全局的内存位置。如果答案不包括术语堆栈或堆,则它们宁愿不与C++相关。对象具有自动或动态存储持续时间。我说过“首选的做法通常是…”。我们真的有分歧吗?+1因为这个答案的质量——也许否决票是个错误?:)
    Player * a; // Allocated an int value to stored an address, you will able to access to value at that address by a -> but you have to allocated it and free when it done
    
    Player a; // Allocated a block of memory that size equal = Player size.