如何将值分配给非类类型?

时间:2017-07-07 14:51:59

标签: c++

如果非类类型(如指针和int)没有构造函数之类的成员函数,那么如何为它们赋值? 例如:

int x = 1;
int p = x;
p = 2;
int a = int();

当我做int p = x;时,它只是执行浅拷贝,就像隐式拷贝构造函数一样?所有其他隐式成员函数也是如此,因为非类型类型在这些情况下的工作方式与类类型相同。

此外,当你有一个类时,该类可能有一个存储某个值的对象(如果该类应该表示一个值),但是这些非类类型是否有某种缓冲区?否则,如何将值从一个值复制到另一个值?

3 个答案:

答案 0 :(得分:1)

为了更好地理解内置类型的语义,请考虑C ++语言的设计和演变。

最初没有C ++,只有C.在C中,没有类,只有内置类型 - 例如int s,float s,指针等等。变量的每个定义都意味着足以存储这种类型的变量的空间以某种方式分配(该分配可以是实际存储器保留的,或者可能仅仅是CPU寄存器的指定)。稍后,对此变量的所有访问都将路由到指定的空间。根本不存在构造函数或析构函数,并且将一个变量复制到另一个变量只是意味着复制源代码的内容' space'进入目标。

后来,当C ++被引入时,我们付出了巨大努力,使遗留的C程序尽可能地与新语言兼容。这意味着,内置类型的行为与C中的行为完全相同。它仍然是真实的。每当你定义一个内置类型的变量(由于它可以不被优化器优化)时,就会为它分配一个空间,并且所有访问都被路由到这个空间。复制这些类型始终是从目标到源的直接空间复制。

答案 1 :(得分:1)

  

如果非类类型(如指针和int)没有构造函数之类的成员函数,那么如何为它们赋值?

构造函数不是魔法。编译器和计算机不会随意发现自己无法执行基本的内存复制操作,因为类型没有构造函数的概念。

内部逻辑类似,但复制操作更简单。复制构造函数是一种在类的成员上进行组合操作的方法,类本身可以是其他类实例或内置类型。内置类型是"基础案例"我可以向你保证编译器知道如何生成代码来复制它们。

当然,因为它们是"基础案例",所以没有有意义的应用术语"浅拷贝"和#34;深拷贝"这里 - 副本是副本是副本。 int没有可以复制或不复制的间接资源,这是使用类和指针进行浅/深复制的地方。

对编译器如何工作的更深入分析超出了范围。

答案 2 :(得分:-2)

在C ++原语类型中,(bool,char,short,int,long,double,float)是可以直接存储在CPU寄存器中的值。

当CPU获得变量声明时,它会获取RAM来存储该值。在C ++ 11及更高版本中,将采用value-initialization的附加步骤。

分解您的代码:

int x = 1;

这将为int获取足够的RAM(通常为4个字节),将符号x与获取的RAM的地址相关联,并将该地址的RAM分配给值1.

int p = x;

这将为另一个int获取足够的RAM,将其与符号p相关联,并将存储在与符号x相关联的地址中的值复制到新地址的RAM中。

p = 2;

这将转到与符号p关联的RAM地址,并用2覆盖其中的值。

int a = int();

它获取另一个int大小的RAM,将RAM的地址与a相关联,调用no-argument int转换函数,并将返回值(0)分配给RAM的地址。 / p>

输入指针

为了深入了解底层机制,C ++为RAM中的两个位置的变量分配内存:堆栈和堆。 当您使用语法int g;声明变量时,关联的ram是一个堆栈地址,并且在输入声明的范围(由{}分隔的代码的一部分)声明输入时获取使用,并保持分配,直到退出范围,此时它被解除分配。

指针操作类似: 如果你宣布

int* k;

指针的空间在堆栈上分配,地址处的值为garbage,或者C ++ 11的值初始化为null。要将对象分配给指针,请使用new运算符

k = new int(2)

分配足够的堆RAM来保存int,用值2初始化该RAM,并将分配的RAM的地址指定为堆栈地址k的值。