如果不使用new操作符进行初始化,C++是否会像对待值类型一样对待类对象?

问题描述 投票:2回答:6

示例代码。

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;

就会被当作值类型处理?

#ifndef MYITEMTYPE_H
#define MYITEMTYPE_H

class MyItemType{

public:
    int someNumber;
    MyItemType();
};

MyItemType::MyItemType(){
}

#endif  /* MYITEMTYPE_H */
c++ value-type reference-type
6个回答
5
投票

它并没有被当作一个值类型,事实上它就是一个值类型。

在Java中,对象变量存储的是对对象的引用,而在C++中,对象和它的引用是有重要区别的。赋值在默认情况下确实是按值来的。

如果你想让一个变量只是一个引用,你可以使用引用或指针类型,这取决于你想对它做什么。这些类型被声明为 T*T&.

再来说明一下。

在Java中,当你说 MyClass obj对象被创建,但一个引用指针被存储在变量 obj.

在C++中。MyClass obj 创建对象并将其存储在 obj. 如果你想使用引用指针,你需要明确地将变量声明为 MyClass* objPointerMyClass& objReference.


7
投票

基本上,是的(如果你认为C++的等价物与Java中的意思相同)。

AClassType anInstance; 是一个对象,而不是一个引用。MyItemType aMyItemType b 是不同的对象,它们驻留在不同的内存空间,所以显然对一个对象的改变不会影响另一个。

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

a.someNumber = b.someNumber;

4
投票

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

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


4
投票

虽然C++没有把对象称为值类型或引用类型,但在C++中,值类型和引用类型的行为具有等价性。

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

  1. 价值类型:复制 b 变成 a 保持它们是独立的对象。
  2. 引用类型复制了 b 变成 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

Pointersreferences可能是指向value对象, 对象由 new 或其他内存管理方案(如 malloc 或Win32 CoTaskMalloc).


2
投票

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

b = a;

你使用的是复制赋值运算符,也就是说这个符号在这里。=.

这个操作符的默认行为是应用成员间的复制,所以如果你没有定义overload你自己的操作符,这条记录将复制所有存储在 a 在相应的成员中 b.

new 操作符就完全不同了,它经常用来在堆上分配对象,用指针管理对象,避免堆和不必要的拷贝。


0
投票

默认情况下,C++将其类视为值类型,并进行深层(元素方面)复制。

但是你可以将你的成员变量存储在类内部的自由存储中(堆上),并自定义(覆盖)赋值操作符的行为(在你的代码中b = a),以显示引用类型的行为。

这(还有一些其他的 "技巧")是为了举例说明,shared_ptr智能指针是如何设计的。它是一个C++类,每个实例都引用相同的原始数据,不管它被复制的频率如何。

© www.soinside.com 2019 - 2024. All rights reserved.