调用构造函数来初始化变量

时间:2015-01-07 16:57:14

标签: c++ class

我在C ++中有以下类定义:

class foo {
private:
   int      a,b,c;

   foo();     // constructor
   void     setup(int x, int y);
   void     some_function_that_changes_a_b_c();
}


foo::foo() {
   a = b = c = 0;
}

void foo::setup(int x, int y) {
    foo();    // <-- I use this to make sure a,b,c are initialized
    a = x;
    b = y;    // <-- c is left unchanged!
}

void foo::some_function_that_changes_a_b_c() {
    // here's some code that changes variables a,b,c
}

然后我有一个使用这个类的代码:

foo  *a = new foo;
a->setup(1,2);
a->some_function_that_changes_a_b_c();
a->setup(5,7);   // <-- HERE IS THE PROBLEM

问题是在第二次调用setup()时,它没有运行foo()构造函数来重置我的值或a,b,c,所以c变量保持在调用时的旧值some_function_that_changes_a_b_c(),我用调试器对它进行了测试,看起来在第二次调用时,foo()正在为变量寻址不同的内存空间。

有没有办法解决这个问题?

4 个答案:

答案 0 :(得分:4)

在C ++中,构造函数只在构造对象时调用一次,而不再在类方法中调用。在你的代码中

void foo::setup(int x, int y) {
    foo();  // ==> this line
}

将创建一个临时foo对象,该对象独立于当前this对象,因此abc字段this对象将保持不变。

为了做到你的想法,创建一个类方法,说foo::reset(),然后从foo::setup()内部调用它。

答案 1 :(得分:1)

创建对象后,不应调用构造函数。将功能放入受保护的reset()函数中,该函数从构造函数和setup函数中调用。

背景:您在foo()中对setup的调用不会重新初始化对象,但会创建一个从未使用过的第二个本地对象。通常,除非您完全知道自己在做什么,否则应该避免显式调用构造函数。

答案 2 :(得分:1)

foo();    // <-- I use this to make sure a,b,c are initialized

不幸的是,它并没有这样做。它创建并销毁临时对象。你不能直接调用构造函数;它们仅用于在生命开始时初始化对象。

您可以使用刚刚初步化的对象重新分配对象:

*this = foo();

或者您可以将构造函数的主体移动到reset函数中,并在需要恢复初始状态时调用它。

我首选的选项是使用单独的对象,而不是尝试重用已修改的对象,并在初始化每个对象时执行所有“设置”:

foo a(1,2);
a.some_function_that_changes_a_b_c();
foo b(5,7);  // known to be in a freshly initialised state

答案 3 :(得分:0)

您尝试做的是两阶段初始化。这在C ++中是不必要和笨拙的。你需要实现两件事

  1. 在对象创建时调用构造函数

  2. 如果你有一个对象说f.setup(1, 2, 3);,那就意味着构造函数必须已经运行了。

  3. 现在:

    foo f; // calls foo() with f
    f.setup(1, 2, 3); // foo() has arleady been called
    
    正如Ying Xiong指出的那样,foo()行会创建一个与您正在使用的this无关的临时对象。

    您可以让构造函数获取变量并进行初始化,而不是两个阶段初始化(构造函数,然后是初始化程序)

    class foo {
      private:
       int      a,b,c;
      public:
       foo(int x, int y, int z);     // constructor
    };
    
    foo::foo(int x, int y, int z)
       : a(x),
       b(y),
       c(z)
    { }
    

    然后使用您想要的值构建

    foo f(1, 2, 3);
    

    如果您每次调用setup时都需要“重置”这些值,那么您最好使用reset函数或类似函数。尝试自己调用构造函数是可能的,但不是很健康。

    void foo::reset() {
        a = b = c = 0;
    }