当新的运算符被覆盖时,C++类构造函数被调用两次 - 为什么

3mr*_*3mr 3 c++

我编写了以下代码来解释运算符new

#include <iostream>

using namespace std;




class Dog {

public:
    Dog() {
        cout << "Dog constructed\n";
    }

    //overriding the new operator of the class and explicitely doing what it internally does
    void* operator new(size_t n) {
        cout << "operator new overriden in Dog class called size_t n = " << n << " Sizeof(Dog) = "<< sizeof(Dog) << endl;

        //Allocating the memory  by calling the global operator new 
        void* storage = ::operator new (n);

        // you can now create the Dog object at the allcated memory at the allocated memory

        ::new (storage) Dog(); //---------> Option 1 to construct the Dog object --> This says create the Dog at the address storage by calling the constructor Dog()

        return storage;
    }

    int m_Age = 5;
    int m_Color = 1;
};

void* operator new(std::size_t size)
{
    void* storage = malloc(size);
    std::cout << "Global operator new called - Asked for: " << size
        << ", at: " << storage << std::endl;
    return storage;
}


int main(int argc, char** argv)
{



    cout << "calling new Dog" << endl;
    Dog* ptr = new Dog;
    int x;
    cin >> x;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我运行它时,输出如下

================================================

叫新狗

Dog类中的operator new overriden,名为size_t n = 8 Sizeof(Dog)= 8

全局运营商新召集 - 要求:8,at:0xf15c20

狗构造

狗构造

==========================================

任何想法为什么Dog对象Dog的construcor被调用两次?

谢谢

use*_*670 8

这是因为你在重构的Dogoperator new中使用placement new来构造一个对象,同时为object正在构造的Dog分配存储空间:

::new (storage) Dog();
Run Code Online (Sandbox Code Playgroud)

operator new永远不应该构造一个对象,它应该只分配内存,编译器将使用分配的内存发出代码来构造一个对象.

  • @ 3mr`:: new(storage)Dog();`是一个新的贴片,它不分配任何内容,只使用提供的存储构造对象.它不应该在重载的`operator new`中使用 (2认同)