我想运行1000次迭代的程序,所以在main中设置一个1000的计数器。我需要在每次迭代后重新初始化各种变量,并且因为类构造函数已经写出了所有初始化 - 我决定在每次迭代后调用它,每次迭代的结果都存储在main中的变量中。
然而,当我打电话给构造函数时,它没有任何影响......我花了一段时间才弄明白 - 但它没有重新初始化任何东西!
我创建了一个与构造函数完全相同的函数 - 因此对象将拥有自己的版本。当我打电话给它时,它按照我的预期重新初始化了所有内容。
int main()
{
Class MyClass()
int counter = 0;
while ( counter < 1000 )
{ stuff happens }
Class(); // This is how I tried to call the constructor initially.
// After doing some reading here, I tried:
// Class::Class();
// - but that didn't work either
/* Later I used...
MyClass.function_like_my_constructor; // this worked perfectly
*/
}
......有人试图解释为什么我做错了,或者没有用,或者是愚蠢的或者你有什么?我的意思是 - 在心理上,我只是想 - 废话,我可以调用这个构造函数并重新初始化所有这些东西。构造函数(理想情况下)是否仅在创建对象时调用?
答案 0 :(得分:8)
您的行Class();
会调用类Class
的构造函数,但它会调用它来创建“临时对象”。由于您不使用该临时对象,因此该行无效。
临时对象(通常)在它们出现的表达式的末尾消失。它们对于作为函数参数传递或初始化其他对象很有用。仅仅在声明中创建一个几乎从来没有用。该语言允许它作为一个有效的表达式,只是对于大多数类而言它并没有那么多。
C ++中没有办法在已经构造的对象上调用构造函数。 C ++对象的生命周期是一个构造,一个是破坏。这就是它的工作原理。如果你想在它的生命中重置一个对象,你做了正确的事情,即调用一个函数来重置它。根据您的类,您可能不需要编写一个 - 默认的赋值运算符可能完全符合您的需要。那时临时可以派上用场:
Class myObject;
// ... do some stuff to myObject ...
myObject = Class();
使用新构建的临时值中的值更新myObject
。它不一定是最有效的可能代码,因为它创建一个临时的,然后复制,然后销毁临时,而不是仅仅将字段设置为其初始值。但除非你的班级很庞大,否则千万次这样做不太可能需要花费相当多的时间。
另一种选择是为每次迭代使用一个全新的对象:
int main() {
int counter = 0;
while (counter < 1000) {
Class myObject;
// stuff happens, each iteration has a brand new object
}
}
请注意,Class MyClass();
不定义类型为Class的对象,称为MyClass,并使用无参数构造它。它声明了一个名为MyClass的函数,该函数不带参数,并返回Class类型的对象。据推测,在您的实际代码中,构造函数有一个或多个参数。
答案 1 :(得分:5)
该行阅读会发生什么......
Class ();
你实际上是否正在调用构造函数 - 对于从头开始构造的临时对象,然后由于你没有对它做任何事情而立即被破坏。它非常类似于转换为Class,它使用构造函数调用创建一个值,除了在这种情况下没有要转换的值,因此使用默认构造函数。
然后编译器可能会将此临时优化掉,因此根本没有构造函数 - 我不确定是否允许这样做。
如果要重新初始化成员,则调用构造函数不是这样做的方法。将所有初始化代码移动到另一个方法中,然后从构造函数中调用它,并在需要重新初始化时使用。
答案 2 :(得分:1)
是的,这不是典型用法。创建一个重置变量的函数,并在需要时调用该方法。
答案 3 :(得分:0)
你成了对c ++的常见误读的牺牲品。新的c ++ 0x使事情更加清晰。
问题是构造语法看起来像函数调用。
void foo( int i ) { }
class Foo { };
Foo(10); // construct a temporary object of type foo
foo(10); // call function foo
Foo{10}; // construct a temporary object of type foo in c++0x syntax
我认为c ++ 0x语法更清晰。
您可以使用此语法执行所需操作。但要注意它非常先进,你应该不这样做。
MyClass.~Class(); // destruct MyClass
new( &MyClass ) Class;
答案 4 :(得分:0)
有了这样的要求,我通常会写一个clear()
(公共)方法。我从构造函数析构函数中调用它。用户代码可以随时调用它。
class Foo
{
public:
Foo() { clear(); }
~Foo() { clear(); }
void clear(); // (re)initialize the private members
private:
// private members
};
要回答这里的问题,只要在初始构建之后需要重新初始化类,就可以调用clear()
方法。