C++11 用默认构造的对象替换堆栈上的现有对象

C++11 用默认构造的对象替换堆栈上的现有对象,c++11,initialization,C++11,Initialization,我想知道在不使用delete和new的情况下返回对象初始值的最佳/正确方法(所有内容都必须保留在堆栈上) 在这两个类中: static const int defaultValue{15}; class Foo { private: int val1{defaultValue}; short val2{4}; } class LongStandingObject { public: void resetFoo(int index); privat

我想知道在不使用delete和new的情况下返回对象初始值的最佳/正确方法(所有内容都必须保留在堆栈上)

在这两个类中:

static const int defaultValue{15};
class Foo
{
  private: 
     int val1{defaultValue};
     short val2{4};
} 
class LongStandingObject
{
   public:
     void resetFoo(int index);
   private:
     Foo foos[100];
}
如果我需要将一些
foo
重置为它们的默认值,那么最好的方法是什么

  • Foo

    void Foo::reset()
    {
       val1 = defaultValue;
       val2 = 4;
    }
    
    我真的不喜欢让值来自两个不同的地方,我喜欢让默认值出现在变量声明旁边的标题中

  • 替换为本地创建的Foo

    void LongStandingObject::resetFoo(int index)
    {
       foos[index] = Foo();
    }
    
    当局部变量被破坏时,我会遇到麻烦吗

  • 使用memcpy

    void LongStandingObject::resetFoo(int index)
    {
       Foo foo;
       memcpy(foos[index], &foo, sizeof(Foo));
    }
    
    也许不太可读

  • 还有别的方法吗


  • 您可以对每个变量使用std::pair。使用
    variable.first=variable.second=value
    初始化。之后,每次要更新所设置的变量时:
    variable.second=new\u value
    。要恢复到原始状态时,可以设置:
    variable.second=variable.first
    。您可以通过编写宏
    RestoreDefault(var)
    来提高代码的可读性

    例如:

    #define RestoreDefault(var) ((var).second = (var).first)
    
    // int val1{180}; // Instead of this line
    std::pair<int,int> val1{ 180,180}; // <- this line
    
    val1.second = 456;
    RestoreDefault(val1);
    
    定义RestoreDefault(var)((var.second=(var.first) //int val1{180};//而不是这条线 std::pair val1{180180};// 你的#2很好,可能是最清晰的

    void LongStandingObject::resetFoo(int index)
    {
       foos[index] = Foo();
    }
    
    这里没有对象生存期问题:在
    foos[index]
    上调用赋值操作符,以更改其值以匹配从
    Foo()物化的临时对象。也就是说,代码与

    {
        Foo tmp;
        foos[index].val1 = tmp.val1;
        foos[index].val2 = tmp.val2;
    }
    
    如果启用了优化,几乎任何编译器都可以直接修改
    foos[index]
    ,而无需实际创建临时
    Foo

    如果您确实想要一个
    Foo::reset()
    函数,您可以使用相同的方法:

    void Foo::reset()
    {
        *this = Foo();
    }
    

    我会避免使用
    memcpy
    ,因为如果您对
    Foo
    进行更改,使其不再具有可复制性,那么程序就会变得不正确。

    你好,谢谢您的回答,但复制每个Foo对象的每个变量只是为了保持默认值可用,这听起来不是一个好主意。特别是在我的例子中,对于内存有限的嵌入式设备,即使是在普通计算机上,也会浪费内存。我还举了一个例子,说明如何在阵列上以精明的方式实现这一原理。选择哪一个取决于您寻求实现的粒度以及变量的类型。原则是保留一对:默认值为第一个,修改后的值为第二个。感谢aschelper,这是我首选的解决方案,但我想确保它是正确的,事实上,一经解释,它看起来非常合乎逻辑;)谢谢你对memcpy的警告
    {
        Foo tmp;
        foos[index].val1 = tmp.val1;
        foos[index].val2 = tmp.val2;
    }
    
    void Foo::reset()
    {
        *this = Foo();
    }