调用构造函数初始化变量

Call constructor to initialize variables

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

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
}

然后我有一个使用这个 class:

的代码
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() 正在为变量寻址不同的内存 space。

有办法解决这个问题吗?

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

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

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

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

将创建一个临时的 foo 对象,它独立于当前的 this 对象,因此 abc 字段也是如此11=] 对象将保持不变。

为了实现您的想法,创建一个 class 方法 ,说 foo::reset(),然后从内部调用它 foo::setup().

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

不幸的是,它不会那样做。它创建和销毁一个临时对象。您不能直接调用构造函数;它们仅用于在生命周期开始时初始化对象。

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

*this = foo();

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

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

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

您正在尝试做的是两阶段初始化。这在 C++ 中是不必要且笨拙的。你需要意识到两件事

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

  2. 如果你有一个对象说f.setup(1, 2, 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" 值,那么最好使用 reset 函数或类似函数。尝试对自己调用构造函数是可能的,但不是很健康。

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