考虑一个类“B”,它包含按特定顺序排列的简单 char
成员变量。
class B {
char x1;
char x2;
char x3;
char x4;
}
我有一个缓冲区 A
,它已包含与 B
中定义的顺序相同的数据。另一个进程已将数据加载到 A
。
char A[4];
是否可以在构造函数不复制数据的情况下构造一个包含
A
数据的B
类型的对象?也就是说,我想将一个B
对象“覆盖”到A
缓冲区上,这样我就可以对数据使用B
方法,而不会导致拷贝或内存分配的开销。假设问题 1 有一个解决方案,是否有任何理由我不能同时定义一个派生自
B
的类D
并且它具有引用B
的成员变量的方法,但它本身不包含新的成员变量?
最佳答案
由于 A
不是 B
,因此没有合法的方法将 A
视为 B
.也就是说,如果 A
是标准布局类,那么您应该能够转换它并且它会“工作”但它不会合法。例如
struct A
{
char data[6] = "hi 0/";
int a = 10;
int b = 20;
};
struct B
{
char x1;
char x2;
char x3;
char x4;
char x5;
char x6;
};
std::ostream& operator <<(std::ostream& os, B& b)
{
return os << b.x1 << b.x2 << b.x3 << b.x4 << b.x5 << b.x6;
}
int main()
{
A a;
B* b = reinterpret_cast<B*>(&a);
std::cout << *b;
}
这是可行的,因为数组和成员在每个类中占用相同的内存部分,但这并不能保证。 B
中的 x1
之后可能会有填充,这意味着并非所有成员都将映射到数组。
现在,如果你重写 B
以拥有一个数组而不是单独的成员,比如
struct A
{
char data[6] = "hi 0/";
int a = 10;
int b = 20;
};
struct B
{
char data[6];
};
然后你可以使用一个 Union 来保存 A
和 B
,因为 B
有相同的 common initial sequence作为 A
使用 b
是合法的。这可能看起来像
union Converter
{
Converter() : a{} {}
A a;
B b;
};
std::ostream& operator <<(std::ostream& os, B& b)
{
return os << b.data;
}
int main()
{
Converter c;
std::cout << c.b;
}
现在类型转换不见了,我们有一个 guarantee from the standard这是安全的
关于c++ - 我可以在不分配内存或复制数据的情况下构造一个对象吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49864796/