【问题标题】:migrating from calloc() to new从 calloc() 迁移到 new
【发布时间】:2018-06-14 15:25:22
【问题描述】:

我遇到了一个大型 pod 结构,我想在其中添加一个 std::vector 成员。

struct LargePodStruct {
    float x,y,z;
    int *arr;
    int sz;
    ...            // dozens of primitive types
    std::vector<int> the_new_vector;
};

为了给这个结构添加一个vector,我需要用new替换这个结构的所有calloc()实例化。

另外,我需要将每个现有成员实例化为零。 但是,添加一个将每个成员实例化为零的默认构造函数是一项平凡的任务。以后也很容易忘记实例化一个新成员。

LargePodStruct::LargePodStruct()
    x(), y(), z(), arr(), sz(), ... // +dozens of instantiations
{}
  1. 有没有更简单的方法来实例化这个结构的原始成员?

  2. 是否还有一种很好且优雅的方法来对工会成员进行零实例化?

.

struct LargePodStruct {
    float x,y,z;
    int *arr;
    int sz;
    ...            
    union { 
        int i;
        void *ptr;
     } u;
    std::vector<int> the_new_vector;
};

【问题讨论】:

  • 你可以试试memset()
  • 考虑直接在类定义中为所有成员添加默认成员初始化器,例如int * arr = nullptr;int sz = 0;
  • 从 C++11 开始,您可以在声明中直接初始化它们,例如:int sz = 0;
  • @GrimFandango 我不熟悉它,但它被描述为here
  • @kiner_shah,(+1) 你的提议是 c++98 的唯一选择。

标签: c++ c++98 construction


【解决方案1】:

可以继续使用calloc() 分配原始内存块,然后使用placement-new 在该内存块内构造结构:

void *buffer = calloc(1, sizeof(LargePodStruct));
LargePodStruct *s = new(buffer) LargePodStruct;

但是,你不能使用delete来释放结构体,你必须直接调用它的析构函数然后free()内存块:

s->~LargePodStruct();
free(buffer);

【讨论】:

  • 为什么不呢? delete 不会打电话给free() 吗?
  • @GrimFandango 不能保证,不,就像 new 不能保证在内部使用 malloc()。您必须正确匹配分配器与其记录的释放器,否则您将有未定义的行为。
【解决方案2】:
template<typename V>
struct zdf{
    V value;
    zdf():value{}{};
    operator V&(){return value;};
    operator V()const{return value;};
    V operator()const{return value;};
    V& operator(){return value};
};

struct LargeModernValue{
    zdf<float> x,y,z;
    std::vector<int> arr;
    std::any u;/*std::variant<int,void*> u;*/
    //....
    std::vector<int> theNewVec;
};

【讨论】:

    猜你喜欢
    • 2014-11-26
    • 1970-01-01
    • 2017-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-04
    • 2011-04-26
    • 2015-07-23
    相关资源
    最近更新 更多