这个new操作符的使用有什么问题?

3

这个可以吗?

Object::Object()
{
    new (this) Object(0, NULL);
}

4
不好的想法。成员没有被正确销毁。而且要维护它需要向stackoverflow.com提问以询问是否是一个好主意。 - Martin York
3个回答

9

使用new(this)将重新构造成员变量。由于它们没有首先被析构,这可能导致未定义的行为。通常的做法是使用一个帮助函数代替:

class Object {
private:
  void init(int, char *);
public:
  Object();
  Object(int, char *);
};

Object::Object() {
  init(0, NULL);
}

Object::Object(int x, char *y) {
  init(x, y);
}

void Object::init(int x, char *y) {
  /* ... */
}

那么,在this上使用placement new本身是否是未定义的行为,还是仅取决于类具有哪些成员而可能是未定义的行为?如果该类只有POD类型的成员,这样做是否安全? - Rob Kennedy
假设其他陷阱(虚函数等)也被避免,那么潜在的情况下,构造函数和析构函数的行为是相当明确的。如果所有成员都是POD,则初始构造函数和放置new都不会执行任何操作。 - MSalters

2

我相信您希望使用委托构造函数,就像Java一样,但这在目前还不支持。当C++0x到来时,您可以这样实现:

Object::Object() : Object(0, NULL)
{

}

你是不是想说C++0x?尽管它要到201x年才准备好,但它的名称仍然是C++0x。如果你真的是想说C++1x,那么这个回答就特别没有帮助了。 - Rob Kennedy
我曾经称它为C++0x,但现在不再是了 :( - Khaled Alshaya
语法无论如何都是错的 - C++0x构造函数委托将是Object::Object() : Object(0, NULL) { }。 - bdonlan
@AraK 在那段语法中不应该有分号。正确的语法看起来应该非常像成员变量初始化。 - Drew Dormann

0
如果 Object 是一个 POD 类型,你可以用以下方式初始化它:
class Object
{
  int x;
  int y;
  // ...
public:
  Object() { memset( this, 0, sizeof Object ); }
};

我们还没有看到双参数构造函数的实现,因此我们不知道全零位是否真正是所需的表示形式。特别地,我们不知道在这个系统上空指针是否为全零位。 - Rob Kennedy
这似乎有点靠不住... 然后有一天,有人决定从Object继承。 - AndersK
1
类似于 boost::noninheritable 可以用来确保没有人会从 Object 继承。 - Kirill V. Lyadvinsky

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接