调用构造函数初始化变量
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
对象,因此 a
、b
和 c
字段也是如此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++ 中是不必要且笨拙的。你需要意识到两件事
在对象创建时调用构造函数
如果你有一个对象说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;
}
我在 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
对象,因此 a
、b
和 c
字段也是如此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++ 中是不必要且笨拙的。你需要意识到两件事
在对象创建时调用构造函数
如果你有一个对象说
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;
}