【问题标题】:Calling the new operator with two arguments but without assignment使用两个参数但没有赋值调用 new 运算符
【发布时间】:2017-09-13 09:03:49
【问题描述】:

我找到了这段代码,但我不明白为什么它在项目中有效。代码结构为:

class MyClass {
    int value;
};

struct MyStruct {
    MyClass classA;
    MyClass classB;
};

int main() {

    MyStruct myStruct;

    new (&((&myStruct)->classA)) MyClass();
    new (&((&myStruct)->classB)) MyClass();
}

(我添加了内部&符号以创建一个较小的示例。在源代码中 myStruct 是一个指针)。

编译器说

In function int main()
error: no matching function for call to ‘operator new(sizetype, MyClass*)’
    new (&((&myStruct)->classA)) MyClass();
                                         ^
note: candidates are:
note: void* operator new(long unsigned int)
note:   candidate expects 1 argument, 2 provided

也许我错过了一些重要的事情。这是一个大项目,我不能复制它。我无法创建 MWE。我希望有人能向我解释这段代码背后的主要思想,以及我必须改变什么来编译它。

【问题讨论】:

  • 查找placement new
  • 这个(&myStruct)-> 毫无意义。或者至少我希望它不会。
  • 写这段代码的人都知道 C++ 是危险的,但不足以有效地处理它。
  • 我很好奇有人会如何知道新位置,这是一个很少使用的功能;但不知道对象是如何创建的。
  • 如果我添加 #include <new> 似乎可以编译。

标签: c++ new-operator


【解决方案1】:

Placement new 是 C++ 语言功能之一,需要包含适当的标头才能尝试使用它们。

使用placement new 时,表达式必须调用operator new 的重载作为其评估的一部分。 这个重载,确切地说:

void* operator new (std::size, void*);

但是这个函数并不是在每个翻译单元中自动为你声明的。因此,要将其拉入,您必须包含正确的标题 (<new>)。


作为旁注,您显示的代码非常损坏。它构造了myStruct 的成员两次!对于非平凡的案件,这可能会造成严重破坏。

非常显式地初始化myStruct 的正确方法是这样的:

MyStruct myStruct {
  {}, // Default construct classA
  {}  // Default construct classB
};

【讨论】:

  • 好答案 - 旁注;甚至不需要显式初始化;它自己的默认构造函数将使对象保持相同的状态 - 对于本例。
  • @UKMonkey - 这是真的。因此,我对此的讽刺是 very 显式初始化:)
猜你喜欢
  • 2013-04-29
  • 1970-01-01
  • 2015-12-14
  • 2017-01-14
  • 2020-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-18
相关资源
最近更新 更多