c++ - 我可以在不分配内存或复制数据的情况下构造一个对象吗?

标签 c++ constructor

考虑一个类“B”,它包含按特定顺序排列的简单 char 成员变量。

class B {
    char x1;
    char x2;
    char x3;
    char x4;
}

我有一个缓冲区 A,它已包含与 B 中定义的顺序相同的数据。另一个进程已将数据加载到 A

char A[4];
  1. 是否可以在构造函数不复制数据的情况下构造一个包含A 数据的B 类型的对象?也就是说,我想将一个 B 对象“覆盖”到 A 缓冲区上,这样我就可以对数据使用 B 方法,而不会导致拷贝或内存分配的开销。

  2. 假设问题 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 来保存 AB,因为 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/

相关文章:

c++ - 如何在 C++ 中声明一个对象,该对象具有来自另一个类的类数据以及带参数的构造函数

javascript - 从类静态方法调用 ES6 类构造函数

c++ - 使用 minizip 解压 char 数组

c++ - 多态类型的连续存储

c++ - Python:如何检查...?

java - 在类的构造函数上使用 protected 访问修饰符

validation - 工厂构造函数中的参数验证?

c++ - 在类的构造函数中初始化 ifstream 变量

c++ - 展开和堵塞对大循环的影响

c++ - 调用子类 QWidget 的方法