4

示例代码:

MyItemType a;
MyItemType b;
a.someNumber = 5;
b = a;

cout << a.someNumber << endl;
cout << b.someNumber << endl;

b.someNumber = 10;

cout << a.someNumber << endl;
cout << b.someNumber << endl;

输出:

5
5
5
10

如果 a 和 b 是引用类型,我猜最后两行应该是 10 和 10 而不是 5 和 10。

这是否意味着当您执行这样的声明时:

AClassType anInstance;

它被视为值类型?

------这里是MyItemType.h------------

#ifndef MYITEMTYPE_H
#define MYITEMTYPE_H

class MyItemType{

public:
    int someNumber;
    MyItemType();
};

MyItemType::MyItemType(){
}

#endif  /* MYITEMTYPE_H */
4

6 回答 6

8

基本上,是的(如果您认为 C++ 等效于 Java 中的含义)。

AClassType anInstance;是一个对象,而不是一个引用。MyItemType a并且 MyItemType b是不同的对象,它们驻留在不同的内存空间中,因此显然对一个对象进行更改不会影响另一个对象。

当你这样做时a=b,你不会用另一个对象来引用一个对象,但是,在这种情况下,做一个成员分配。基本上就像说

a.someNumber = b.someNumber;
于 2012-11-29T20:09:29.337 回答
6

它不被视为值类型,事实上它是。

虽然在 Java 对象变量中存储对对象的引用,但在 C++ 中,对象与其引用之间存在重要区别。默认情况下,赋值实际上是按值分配的。

如果您希望变量只是一个引用,您可以使用引用或指针类型,这取决于您想要使用它。这些类型被声明T*T&.

为了进一步说明这一点:

在 Java 中,当您说 时MyClass obj,创建了一个对象,但在变量中存储了一个引用/指针obj

在 C++ 中,MyClass obj创建对象并将其存储在obj. 如果要使用引用/指针,则需要将变量显式声明为MyClass* objPointerMyClass& objReference

于 2012-11-29T20:12:40.053 回答
4

虽然 C++ 不调用对象值或引用类型,但值和引用类型的行为在 C++ 中是等价的。

给定两个对象ab, a = b:

  1. 值类型将 的内容复制ba保持它们单独的对象中;
  2. 引用类型复制binto的位置a,使它们引用同一个对象。

对于 C++:

MyClass  a;      // value type
MyClass  b;      // value type
MyClass &c =  a; // reference type (a reference in C++), fixed to a
MyClass *d = &b; // reference type (a pointer in C++)

 a =  b; // copy content of b into a
 c =  b; // copy content of b into a
 d = &a; // set d to refer to a
*d =  b; // copy content of b into a

指针/引用可以指向值对象、由分配的对象new或一些其他内存管理方案(例如malloc,或 Win32 CoTaskMalloc)。

于 2012-11-29T20:23:33.737 回答
4

在 C++ 中,对象在没有指针引用的情况下创建时被称为静态(堆栈)变量。动态(堆)变量是需要手动内存管理的指针引用。

相比之下,在 Java 或 C# 中,几乎所有对象都是引用类型,其行为类似于指针,只是它们被垃圾收集,而值类型是所有通常不可变的对象的特殊子集。(C++ 堆栈变量当然不是不可变的)。

于 2012-11-29T20:14:09.723 回答
2

简短的解释在这个关键部分

b = a;

您正在使用复制赋值运算符,即此处的符号=

此运算符的默认行为是应用逐个副本,因此如果您不定义/重载自己的运算符,此行将复制存储ab.

运算符new是完全不同的故事,它通常用于在堆上分配对象并使用指针管理它们,避免堆栈和不必要的副本。

于 2012-11-29T20:14:58.877 回答
0

默认情况下,C++ 将其类视为值类型并进行深度(元素方式)副本。

但是您可以将成员变量存储在类中的免费存储空间(在堆上)并自定义(覆盖)赋值运算符(代码中的 b = a)的行为以显示引用类型的行为。

这(以及其他一些“技巧”)是用于示例 shared_ptr 智能指针的设计方式。它是一个 C++ 类,其中每个实例都引用相同的原始数据,无论复制的频率如何。

于 2020-06-03T17:49:44.820 回答