C++ 这是一个新问题

C++ 这是一个新问题,c++,C++,我看到一些代码如下: class BaseClass { public: BaseClass(int param); }; class Derived: public BaseClass { }; BaseClass::BaseClass(int param) { new (this) Derived; } 代码试图做什么?我认为它会创建一个派生类对象。然而,背后的逻辑是什么?我认为当我们调用new BaseClass()时,它只会根据基类大小分配内存。然而,为什么我们仍然

我看到一些代码如下:

class BaseClass
{
public:
    BaseClass(int param);
};

class Derived: public BaseClass
{
};

BaseClass::BaseClass(int param)
{
    new (this) Derived;
}
代码试图做什么?我认为它会创建一个派生类对象。然而,背后的逻辑是什么?我认为当我们调用new BaseClass()时,它只会根据基类大小分配内存。然而,为什么我们仍然可以将这个指针传递到新的位置来构造派生类对象呢

编辑: 谢谢你的回复。进一步检查后,代码确实覆盖了基类的new运算符,以分配足够的内存来容纳派生类对象,并避免递归调用它。在派生类构造函数中,它调用了另一个基类构造函数


基本上,我认为它试图创建类似于factory的东西,其中对象的创建取决于参数。根据回复,这样做似乎不是一个好的做法。

这是一种可怕的未定义的行为,大约有六个原因。永远不要这样做。

这是未定义的行为,它可能会递归调用基类构造函数,您将得到无限递归。

这将调用
所指向的内存上的
派生类的构造函数。因此,
new
操作符不分配任何内容,它只调用构造函数初始化已分配内存中的对象

然而,在这种特殊情况下,结果最多也会很奇怪。实际上,您正在使用派生类的构造函数初始化基类的对象。结果是,您仍然拥有基类的对象,但具有派生类的状态,或者至少假装它具有这样的状态。根据派生类是否引入其构造函数引用的一些新字段,这甚至可能导致内存访问冲突


所以,简短的建议是:不要这样做。一般来说,除非你真的知道自己在做什么,否则根本不要使用placement new。

我认为这背后没有任何逻辑。在C++中,当你构建一个派生实例时,首先将对象初始化为一个基(即,首先执行Basic的构造函数)。因此,我认为这段代码将永远递归地调用自己(直到堆栈空间耗尽为止)。

这段代码中有很多错误。对于初学者来说,为了选择简单的构造函数,构造函数不应该在类声明中被限定

下一件事是它看起来在做什么:它看起来在为
Base
分配的内存中创建一个类型为
Derived
的对象

  • 这里的问题包括,
    派生的
    可能需要比
    基本的
    更多的内存,并且不能保证内存可用
  • 它将触发一个无限递归循环,因为
    Base
    的构造函数正试图创建一个
    派生的
    ,该构造函数将反过来尝试调用
    Base
    的构造函数,该构造函数将尝试创建一个
    派生的
  • 即使递归被切断(提供一个替代的
    Base
    构造函数,并将被调用的
    派生的
    构造函数分派到该非重复版本),并且
    派生的
    适合
    Base
    的内存占用,已初始化的
    Base
    的任何成员都将调用未定义的行为重新初始化。例如,如果
    Base
    包含一个在内部分配和管理内存的属性,那么它的构造函数将被调用两次,泄漏在第一次调用中获取的资源。分别构造和销毁的对象数量将不匹配
  • 可能还有很多其他的问题,直到DeadMG提到的六个巴吉利昂数字

您的代码无法编译


没有为
Derived
定义构造函数,编译器无法生成默认构造函数,因为
Base
只有一个需要参数的构造函数。

Ew!嗯嗯!这不是好的代码。沿着这条路走下去就是疯狂,当然,除非其中涉及到(你没有展示出来)——即使这样,它也有很多气味。。。除了由于无限递归而产生堆栈溢出之外,你的意思是?@David:它甚至不编译(
派生的
没有有效的构造函数)。你能用spec/doc/来支持你的答案吗。。。?