如果在没有 new 运算符的情况下初始化,C++是否将类对象视为值类型
Does C++ treat Class Objects like value types if initialized without the new operator?
示例代码:
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 是引用类型,最后 2 行应该是 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 */
是的(如果你认为C++等同于Java的意思
)。 AClassType anInstance;
是一个对象,而不是一个引用。 MyItemType a
和 MyItemType b
是不同的对象,它们驻留在不同的内存空间中,因此显然对一个对象的更改不会影响另一个对象。
当您执行a=b
时,您不会将一个对象与另一个对象一起引用,但在这种情况下,执行成员赋值。这基本上就像说
a.someNumber = b.someNumber;
它不被视为值类型,事实上它是。
在 Java 中,对象变量存储对对象的引用,而在C++中,对象与其引用之间存在重要差异。默认情况下,赋值实际上是按值分配的。
如果希望变量只是引用,则可以使用引用或指针类型,具体取决于您希望使用它的内容。这些类型声明为 T*
和 T&
。
为了进一步说明这一点:
在Java中,当你说MyClass obj
时,会创建一个对象,但是一个引用/指针存储在变量obj
中。
在C++中,MyClass obj
创建对象并将其存储在obj
中。如果要使用引用/指针,则需要将变量显式声明为 MyClass* objPointer
或 MyClass& objReference
。
在C++对象在没有指针引用的情况下创建时,它们被称为静态(堆栈)变量。 动态(堆)变量是需要手动内存管理的指针引用。
相比之下,在 Java 或 C# 中,几乎所有对象都是引用类型,它们的行为类似于指针,只是它们是垃圾回收的,而值类型是通常不可变的所有对象的特殊子集。 (C++堆栈变量肯定不是不可变的)。
虽然C++不调用对象值或引用类型,但值和引用类型的行为在C++中具有等效性。
给定两个对象a
和b
,a = b
:
- 值类型将
b
的内容复制到a
以使它们保持单独的对象; - 引用类型将
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
指针/引用可以是值对象、由new
分配的对象或其他一些内存管理方案(例如 malloc
或 Win32 CoTaskMalloc
)。
简短的解释在这个关键部分
b = a;
您正在使用复制赋值运算符,这意味着此处的符号=
。
此运算符的默认行为是应用成员副本,因此,如果您不定义/重载自己的运算符,此行将复制存储在a
所有成员中的所有值b
的相应成员中。
new
运算符 这是一个完全不同的故事,它通常用于分配堆上的对象并使用指针管理它们,避免堆栈和不必要的副本。
默认情况下,C++ 将其类视为值类型并创建深层(元素)副本。
但是,您可以将成员变量存储在类中的空闲存储(堆上)中,并自定义(覆盖)赋值运算符的行为(代码中的b = a)以显示引用类型的行为。
这个(以及其他一些"技巧")就是为了举例,如何设计shared_ptr智能指针。它是一个C++类,其中每个实例都引用相同的原始数据,无论复制频率如何。
- 是否需要删除包含对象的"pair"?
- 是否删除在对象构造过程中创建的对象
- 当一个新对象被分配到它的地址时,对象是否必须被销毁
- 在这种情况下,java对象是否可以调用本机函数
- 返回指向对象的指针的函数调用是否为 prvalue?
- 具有引用成员的结构是否具有唯一的对象表示形式
- 对象初始化中是否允许指向此成员的指针?
- COM :是否可以查看是否存在对我的某个 COM 对象的进程外引用?我可以释放它吗?
- 堆分配的对象是否存在永不为空的唯一所有者?
- 在函数内创建的对象的范围 - 如果在函数外部存储和访问引用,它们是否有效?
- 是否可以使用一个类来控制 C++ 中另一个类的对象?(阿杜伊诺)
- 在对象指针上调用 Delete 是否会递归删除其动态分配的成员
- QFileSystemModel 对象是否会被删除?
- 具有相同特征的两个对象是否只在内存中存储一次?无论定义它们的函数是什么,都是不同的
- 是否可以使用分配器对象来释放另一个分配器分配的内存?
- 线程调用的函数对对象删除是否安全?
- 将对象的字节复制到数组并再次复制回来是否安全
- std::memmove在同一对象之间是否始终安全
- 类对象在 c++ 中是否具有数据类型?
- 是否可以将不可复制的成员用作使对象不可复制的替代方法?