调用构造函数来初始化变量
Call constructor to initialize variables
我在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() 正在为变量寻址不同的内存空间。
有没有办法解决这个问题?
在C++中,构造函数仅在构造对象时调用一次,不再在类方法中调用。在您的代码中
void foo::setup(int x, int y) {
foo(); // ==> this line
}
将创建一个临时的 foo 对象,该对象独立于当前this
对象,因此this
对象的a
、b
和c
字段将保持不变。
为了做你想做的事情,创建一个类方法,比如foo::reset()
,然后从foo::setup()
内部调用它。
创建对象后,不应调用构造函数。将功能放入从构造函数和setup
函数调用的受保护reset()
函数中。
背景:调用 foo()
in setup
不会重新初始化对象,而是创建第二个从未使用的本地对象。通常,除非你绝对知道自己在做什么,否则你应该避免显式调用构造函数。
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
您尝试执行的是两阶段初始化。 这在C++中是不必要的和笨拙的。 你需要意识到两件事
-
在对象创建时调用构造函数
-
如果你有一个对象要说
f.setup(1, 2, 3);
,这意味着构造函数必须已经运行。
现在:
foo f; // calls foo() with f
f.setup(1, 2, 3); // foo() has arleady been called
正如熊颖所指出的,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;
}
- 为什么C++有不同的变量初始化方式?
- 静态 constexpr 成员变量初始化
- C++不同的变量初始化
- 全局和局部变量初始化与 constexpr 的差异背后的基本原理
- 是变量初始化失败吗?
- 视觉C++:在 DLL 加载期间,全局变量初始化顺序是否具有确定性?
- 类静态变量初始化顺序
- 使用 constinit 变量初始化 constexpr 变量
- 是否可以在不修改父类的情况下将成员变量初始化推迟到继承的类?
- 使用全局变量初始化不同编译单元中的其他全局变量
- 使用默认构造函数引用成员变量初始化错误
- 宏的 if 语句中的变量初始化
- 不稳定的C :每行适应性变化多变量初始化
- 同一函数中的静态函数变量初始化顺序
- C 语言中的静态变量初始化
- 错误:调用'begin(long double [nPoints])'没有匹配函数;使用硬编码的 int 与整数变量初始化向量
- 类POD成员变量初始化
- 尝试捕获类变量初始化的范围
- 共享库中 __attribute__((构造函数)) 的全局/静态变量初始化问题
- 多变量初始化编译器支持