4

这几天一直在苦苦挣扎。

问题是构造函数调用。

我写了一段代码,例如:

#include <iostream>
using namespace std;

class Foo
{

  private: int _n;

  public:

  Foo() { Foo(5);}

  Foo(int n) {_n=n; cout << n << endl; }

};

int main()
{
   Foo* foo = new Foo();
   return 0;

}

当我使用默认构造函数在外面构造一个 Foo 对象时:

Foo* f = new Foo();

我想变量 _n 是 5,但是,它不是。

在 Java 中可以,但在 c++ 中不行。

此外,在 Visual C++ 6 sp 6 中,

Foo() {this->Foo(5);}

作品。

但是,这个表达式被 gcc/g++ 4 拒绝了。

最后,我找到了解决方案。

只需将默认构造函数更改为

Foo() {Foo(5);}

进入

Foo() { new (this) Foo(5); }

解决问题。

括号中的“this”是做什么的?

4

5 回答 5

4

所做的是在所指向的位置(this)创建一个全新的对象(这称为放置新)。您应该只在and的数组中使用它,不要在其他任何地方使用它(而且几乎从不在那里)。由于您在已经开始构建的位置构建 a,因此您所做的是未定义的行为,并且如果您有基类,则会在整个地方泄漏资源。从历史上看,正常的做法只是将初始化移至私有函数。Foothischarunsigned charFoothis

class Foo {
public:    
  Foo() { init(5);}    
  Foo(int n) {init(n);}
private: 
  int _n;
  void init(int n) {
    _n=n;
  };
}

在 C++11 中,构造函数应该能够使用这种语法相互调用,但我不知道哪些编译器支持它。 根据 Apache的说法,GCC 4.7 和 Clang 3.0 支持它,但英特尔 C++ 和 VC++ 尚不支持。

class Foo {
public:    
  Foo() : Foo(5) {}
  Foo(int n) {_n=n;}
private: 
  int _n;
}

您开始的代码Foo() { Foo(5);}开始构造this,然后使用参数 5 在堆栈上创建一个全新的Foo对象,然后销毁它,然后认为自己完全构造,而不初始化它自己的任何值。这就是为什么它编译并运行,但似乎没有做任何事情。

于 2012-07-18T18:50:09.537 回答
3

在 C++11 中,您可以使用委托构造函数来指定它:

Foo() : Foo(5) { }
于 2012-07-18T18:49:15.420 回答
1

(this)括号中的意思是new操作符将使用地址this作为初始化类的地址。

这是非常危险的:你在当前对象的构造函数中,并且你在同一个内存空间上调用了一个新的构造函数。想象一下如果你从另一个类继承会发生什么!

至于您的问题,您不能从构造函数中调用另一个重载的构造函数。典型的解决方案是有一个方法来初始化你的类:

class Foo
{
  int _n;
public:
  Foo() { init(5); }
  Foo( int i) { init(i); }
  void init(int i) { _n = i; }
};

我在这里遇到了同样的问题:又一个 C++ 对象初始化询问;随时查看解决方案。

于 2012-07-18T18:50:22.617 回答
0
Foo() { new (this) Foo(5); }

是一个“placement new”运算符,它在预分配的内存上调用构造函数。

现在,对于您的另一个问题 - C++11 完全允许(相互调用构造函数),但早期的标准(尤其是 MSVC 6 使用的标准)没有,所以使用那些丑陋init()的方法是去找你。

于 2012-07-18T18:49:12.150 回答
0

C++ 中的正确语法是

class Foo { 

  private: int _n; 

  public: 

  Foo() : Foo(5) {} 

  Foo(int n) _n(n) {} // As suggested by another member's edit, initializer lists are preferred

};

或者,C++ 允许默认参数值,例如

Foo(int n = 5);

这允许您编写一个构造函数而不是两个。

此外,您应该确保了解内联函数和非内联函数之间的区别。这种 Java 风格的编程是有效的 C++,但它有其优点和缺点,至少还有一个其他替代方案。

于 2012-07-18T18:46:48.343 回答