3mr
3mr

Reputation: 342

C++ class constructor is called twice when new operator is overriden - why

I wrote the following code to unsderstand the operator 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;
}

When I run this, the output comes as below

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

calling new Dog

operator new overriden in Dog class called size_t n = 8 Sizeof(Dog) = 8

Global operator new called - Asked for: 8, at: 0xf15c20

Dog constructed

Dog constructed

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

Any idea why the Dog object Dog's construcor is called twice ?

thanks

Upvotes: 3

Views: 343

Answers (2)

Caleth
Caleth

Reputation: 63039

It's because you are constructing a Dog in a function that should only allocate space for a Dog. The compiler then constructs a second Dog over that one.

Observe that the return type is void*, i.e. a pointer to unknown. If you were meant to construct a Dog, the return value would be Dog*

Upvotes: 4

user7860670
user7860670

Reputation: 37599

It it because you construct a Dog object using placement new inside of overloaded operator new while allocating storage for Dog object being constructed:

::new (storage) Dog();

Operator new should never construct an object, it should only allocate memory and compiler will emit code to construct an object using the allocated memory.

Upvotes: 8

Related Questions