Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 对内存分配和构造函数的调用是否可以与执行";新";表情?_C++_Class_Constructor_New Operator - Fatal编程技术网

C++ 对内存分配和构造函数的调用是否可以与执行";新";表情?

C++ 对内存分配和构造函数的调用是否可以与执行";新";表情?,c++,class,constructor,new-operator,C++,Class,Constructor,New Operator,假设我有一个下面的类: class Sample { public: Sample( int ) {} }; 某些函数返回一个int int SomeFunction() { return 0; } 该代码: Sample* sample = new Sample( SomeFunction() ); 现在,我期待以下顺序: SomeFunction()运行,然后 ::运行operator new()为对象分配内存,然后 类示例构造函数在分配的内存上运行 这个顺

假设我有一个下面的类:

 class Sample {
 public:
     Sample( int ) {}
 };
某些函数返回一个
int

int SomeFunction()
{
    return 0;
}
该代码:

Sample* sample = new Sample( SomeFunction() );
现在,我期待以下顺序:

  • SomeFunction()
    运行,然后
  • ::运行operator new()
    为对象分配内存,然后
  • 类示例
    构造函数在分配的内存上运行

这个顺序是固定的还是可以通过一个实现来改变,比如说首先分配内存,然后调用
SomeFunction()
,然后运行构造函数?换句话说,调用
操作符new()
函数和调用类构造函数是否可以与任何内容交错?

实际上,我认为发生的是:

  • new用于分配原始内存
  • 调用SomeFunction()返回值X
  • 调用构造函数,并将X作为参数

但我可能错了。我想说,这表明您不应该担心顺序。

您无法更改运行该行代码时发生的情况。您可以运行一些不同的代码行

void * p = ::operator new (sizeof (SomeFunction));
SomeFunction temp;
SomeFunction* sample = new (p) SomeFunction(temp);

顺序未明。[5.3.4]/21内容如下:

是否调用[operator new] 在评估构造函数之前 参数或在评估 构造函数参数,但在 输入构造函数是 未指明。也没有具体说明 参数是否为构造函数 如果[操作员新建] 返回空指针或退出 使用异常


调用运算符new和SomeFunction的顺序未指定-因此它可能会根据优化设置、编译器版本等进行更改


我认为构造函数调用必须位于最后。

是的,它可以是交错的

class A
{
public:
    A(int i)
    {
        cout << "constructor" << endl;
    }
    void* operator new(size_t size)
    {
        cout << "new" << endl;
        return malloc(size);
    }
    void operator delete(void*, size_t)
    {
        cout << "delete" << endl;
    }
};

int f()
{
    cout << "f()" << endl;
    return 1;
}

int main()
{
    A* a = new A(f());
}

Output:
new
f()
constructor
A类
{
公众:
A(国际一)
{

cout+1:唯一必须保持的是分配函数必须在调用构造函数之前返回。@Charles Bailey:True。事实上,唯一可能的序列(假设new不抛出)是:a)运算符new,SomeFunction(),Sample ctor b)SomeFunction(),运算符new,示例代码,但前两个项目符号的顺序可以颠倒。如果某个函数返回指向动态分配内存的指针,则有理由担心顺序,在这种情况下,应重写代码以确保异常安全。这是由哪个编译器发生的?您也可以说如果nt求值抛出一个异常,那么构造函数将根本不会被调用,所以过早调用
new
是一个坏主意!有一点是肯定的,即
SomeFunction()
将始终在构造函数
Sample()
之前被调用。所以问题将仅限于
SomeFunction()之间
操作员新建