【问题标题】:C++ completely erase (or reset) all values of a struct?C ++完全擦除(或重置)结构的所有值?
【发布时间】:2013-03-03 07:25:42
【问题描述】:

所以,我只是想知道我们如何才能完全擦除或重置一个结构以便重复使用?

我刚刚输入了这个,给你:

typedef struct PART_STRUCT
{
    unsigned int Id;
    std::string Label;
} Part;

typedef struct OBJECT_STRUCT
{
    std::vector< unsigned char > DBA;
    std::vector< Part > Parts;
    unsigned int Id;
} Object;

Object Engine;

// Initialize all members of Engine
// Do whatever with Engine
// ...
// Erase/Reset Engine value

【问题讨论】:

  • 那个 typedef 是来自 C 的人工制品,它在这里没有多大作用。也只需重置自己内部的成员或编写一个方法来完成它。
  • 谢谢,我不知道。
  • 天啊,为什么每个人都对反对票如此满意?我 +1 这个回 0。
  • 最简单的解决方案是编写一个重置所有单个成员的方法。在 C 中,当我们确定 0 或 NULL 是其所有成员可接受的初始值时,我们使用memset(&amp;struct_var, 0, sizeof(struct whatever))。但在 C++ 中,很难始终保持这种假设正确。
  • @Slava - 如果构造函数除了初始化值之外还打算做一些额外的事情,那么构造函数可能并不总是重置所有单个成员的解决方案。

标签: c++


【解决方案1】:

你可以给它分配一个临时构造的:

Part my_struct;

my_struct = Part(); // reset

C++11:

my_struct = {}; // reset

【讨论】:

  • 嗯,这似乎不是一个坏主意。
  • @user2117427 要使其正常工作,您的结构中需要适当的默认构造函数
  • @Slava 编译器生成的应该适用于结构。虽然某些成员会未初始化,我认为这是 UB,但如果您懒得编写适当的重置函数,我不会担心这种情况。
  • UB 是什么意思? :0 哦和 +1 :)
  • @user2117427 未定义的行为。 C++ 程序的祸根。
【解决方案2】:

如果出于某种原因,我一心想要始终保持同一个对象,我会编写一个 reset 方法,将所有值重置为原来的值。

类似的东西:

struct Test {
    int a;
    int b;
    Test(): a(0), b(100) {}
    void reset() {
        a = 0;
        b = 100;
    }
};

int main() {
    Test test;
    //do stuff with test
    test.reset(); //reset test
}

【讨论】:

  • @user2117427 如果你不想产生错误,你应该停止。至少从ctor调用reset(),但最好去掉reset()方法
  • @Rapptz 这是容易出错的解决方案,更改 ctor 或重置为不同的值,然后忘记它的配对和繁荣。
  • @Slava 并没有真正地提倡它,无论如何,问题的前提有点糟糕。重用对象对 IMO 来说是一件很奇怪的事情。
  • @Slava 尔什么。您不需要 init 成员来避免代码重复。添加 init 成员会创建不保持不变量的虚假对象状态。有趣的是,您会同时提倡它并谈论代码的正确性。
  • @CatPlusPlus 我不提倡,我说在 c++03 中使用这种技术来避免代码重复(从不同 ctor 调用的私有 init 方法)和在 c++11 中创建的构造函数委托避免这种情况。
【解决方案3】:

好的做法是避免这种类型的构造(使用相同的变量来表示两种不同的语义含义,同时重置它)。当您(或其他人)修改您的代码并忘记您共享一个用于两种不同用途的变量时,它将不可避免地产生一个奇怪的错误。

唯一的理由是节省一些内存空间,但是:

  • 您实际上不太可能需要这样的优化。
  • 即使你这样做了,编译器通常会发现堆栈上的一个变量不再使用并且可以丢弃,你创建的新变量将因此有效地替换第一个变量。你不需要关心自己节省内存。
  • 如果变量在堆上,最好只使用两个不同的指针。

但是如果你真的想要做这个重置,你必须写一个方法来做。 C++ 中没有内置方法,因为它实际上需要调用destructor,然后再次调用constructor

解决方案my_struct = Part() 仅在您的destructor 微不足道时才有效。假设您在std::vector 中分配了指针,在清空vector 之前,您必须正确地delete 每个指针。这就是它不能自动完成的原因:结构的清理可能需要特殊处理而不是简单地忘记。

【讨论】:

  • > my_struct = Part() 的解决方案仅适用于您的析构函数微不足道的情况。什么?
  • 抱歉打错了。为什么是-1?例如,您如何看待boost::shared_ptr?您不想自己调用析构函数,所以我看到的唯一方法是编写reset 方法。
  • my_struct = Part() 工作正常,它也适用于 boost::shared_pointer,所以 -1 因为它不是必须的,并且只重置一个替代方案,我认为不是最好的在这种情况下是一个。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-13
  • 2017-04-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多