Object
对象
C++程序创建、销毁、引用、访问和操作对象
...
对象,在C++中,是存储区域
那就有了。
- 尺寸%28可以用大小29%;
- 对齐要求%28可以用对齐29%;
- 存储时间%28自动,静态,动态,线程-局部%29;
- 寿命%28以存储时间为限或临时为%29;
- 类型;
- 值%28,可能是不确定的,例如默认初始化非类类型%29;
- 可选地,名称...
以下实体不是对象:值、引用、函数、枚举器、类型、非静态类成员、位字段、模板、类或函数模板专门化、命名空间、参数包和this
...
阿变量
不是非静态数据成员的对象或引用,由声明...
对象由定义,,,新表达式,,,抛出表达式,当更改联合,以及在哪里临时对象都是必需的。
对象表示和值表示
类型对象的T
,,,对象表示
是sizeof(T)
类型对象unsigned char
%28或相等于std::byte
%29开始于与T
对象。
大值表示
对象的值是保存其类型值的一组位。T
...
为TriviallyCopyable
类型,值表示是对象表示的一部分,这意味着复制存储中对象占用的字节足以生成值为%28的另一个对象,除非该值是陷阱表示
它的类型并将其加载到CPU中会引发一个硬件异常,例如snan%28“Signal non-a-number”%29浮点值或NAT%28“Not-Thing”%29整数%29。
相反的情况不一定是正确的:TriviallyCopyable
具有不同对象表示形式的类型可以表示相同的值。例如,多个浮点位模式表示相同的特殊值。南.更常见的是,对象表示的某些位可能根本不参与值表示;这些位可能是为满足以下要求而引入的填充。对齐要求,,,位场尺寸等
二次
#include <cassert>
struct S {
char c; // 1 byte value
// 3 bytes padding
float f; // 4 bytes value
bool operator==(const S& arg) const { // value-based equality
return c == arg.c && f == arg.f;
}
};
assert(sizeof(S) == 8
S s1 = {'a', 3.14};
S s2 = s1;
reinterpret_cast<char*>(&s1)[2] = 'b'; // change 2nd byte
assert(s1 == s2 // value did not change
二次
类型对象char
,,,signed char
,和unsigned char
%28,除非它们尺寸过大位字段%29,每一位对象表示都需要参与值表示,而每一种可能的位模式表示一个不同的值%28--不允许填充、陷阱位或多个表示形式--允许%29。
次目标
对象可以包含其他对象,这些对象被调用次目标
.这些包括。
- 成员对象
- 基类子对象
- 阵列元件
不是另一个对象的子对象的对象被调用。完全对象
...
完整对象、成员对象和数组元素也称为大多数派生对象
,以区分它们与基类子对象。a的大小大多数派生对象
那不是位场必须为非零%28,基类子对象的大小可能为零:请参见空基优化29%。
任何两个重叠的对象寿命%28不是位字段%29保证具有不同的地址,除非其中一个地址是另一个地址的子对象或为另一个地址提供存储,或者是在同一完整对象中具有不同类型的子对象,并且其中一个是零大小基。
二次
static const char c1 = ’x’;
static const char c2 = ’x’;
assert(&c1 != &c2 // same values, different addresses
二次
多态对象
声明或继承至少一个虚拟函数的类类型对象是多态对象。在每个多态对象中,实现在每个现有实现中存储附加信息%28,除非优化出%29,否则它是一个指针。虚函数调用和RTTI功能%28动态[医]铸造和类型%29用于在运行时确定创建对象的类型,而不管在其中使用的表达式是什么。
对于非多态对象,值的解释由使用对象的表达式确定,并在编译时确定。
二次
#include <iostream>
#include <typeinfo>
struct Base1 {
// polymorphic type: declares a virtual member
virtual ~Base1() {}
};
struct Derived1 : Base1 {
// polymorphic type: inherits a virtual member
};
struct Base2 {
// non-polymorphic type
};
struct Derived2 : Base2 {
// non-polymorphic type
};
int main()
{
Derived1 obj1; // object1 created with type Derived1
Derived2 obj2; // object2 created with type Derived2
Base1& b1 = obj1; // b1 refers to the object obj1
Base2& b2 = obj2; // b2 refers to the object obj2
std::cout << "Expression type of b1: " << typeid(decltype(b1)).name() << ' '
<< "Expression type of b2: " << typeid(decltype(b2)).name() << '\n'
<< "Object type of b1: " << typeid(b1).name() << ' '
<< "Object type of b2: " << typeid(b2).name() << '\n'
<< "size of b1: " << sizeof b1 << ' '
<< "size of b2: " << sizeof b2 << '\n';
}
二次
产出:
二次
Expression type of b1: Base1 Expression type of b2: Base2
Object type of b1: Derived1 Object type of b2: Base2
size of b1: 8 size of b2: 1
二次
严格混叠
在许多情况下,使用创建对象的类型以外的类型的表达式访问对象是未定义的行为,请参见重释[医]铸造对于异常和示例列表。
对齐
每一个对象类型是否将该属性称为对齐要求
,它是类型的整数值%28。std::size_t
,总功率为2%29,表示可以分配此类型对象的连续地址之间的字节数。类型的对齐要求
可以用对齐或std::alignment_of
指针对齐函数std::align
可用于在缓冲区内获得对齐适当的指针,以及std::aligned_storage
可用于获得适当的对齐存储。
每种对象类型都对该类型的每一个对象施加其对齐要求;可以使用以下方法请求更严格的对齐率%28和更大的对齐要求对齐...
为了满足对齐的要求,所有非静态成员的类,,,填充物
可能会在它的一些成员之后插入。
二次
#include <iostream>
// objects of type S can be allocated at any address
// because both S.a and S.b can be allocated at any address
struct S {
char a; // size: 1, alignment: 1
char b; // size: 1, alignment: 1
}; // size: 2, alignment: 1
// objects of type X must be allocated at 4-byte boundaries
// because X.n must be allocated at 4-byte boundaries
// because int's alignment requirement is (usually) 4
struct X {
int n; // size: 4, alignment: 4
char c; // size: 1, alignment: 1
// three bytes padding
}; // size: 8, alignment: 4
int main()
{
std::cout << "sizeof(S) = " << sizeof(S)
<< " alignof(S) = " << alignof(S) << '\n';
std::cout << "sizeof(X) = " << sizeof(X)
<< " alignof(X) = " << alignof(X) << '\n';
}
二次
产出:
二次
sizeof(S) = 2 alignof(S) = 1
sizeof(X) = 8 alignof(X) = 4
二次
最弱的对齐率%28最小的对准要求%29是char
,,,signed char
,和unsigned char
,等于1;最大的基本对准
的对齐方式。std::max_align_t
如果使类型%27s的对齐比%28大%29更严格std::max_align_t
使用对齐,它被称为扩展对准
要求。扩展其对齐方式的类型或非静态数据成员具有扩展对方式的类类型是过对型
.它是实现-定义为新表达式,,,std::allocator::allocate
,和std::get_temporary_buffer
支持过对齐类型。Allocator
斯如果使用过对齐类型实例化,则允许在编译时无法实例化,从而引发std::bad_alloc
在运行时,默默地忽略不支持的对齐需求,或者正确地处理它们。
另见
C对象文档
*。
© cppreference.com
在CreativeCommonsAttribution下授权-ShareAlike未移植许可v3.0。