Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between “new Foo()” and “&Foo()” as parameters

I have some questions concerning the difference between the keyword new and & in a certain context.

Let’s say this is my code:

struct Base {};
struct Foo : Base {};
struct Storage
{
    void save(Base * object) {}
    Base * content;
};

int main()
{
    Storage s1, s2;
    s1.save(new Foo());
    s2.save(&Foo());
}

After the execution of main, s1 will hold a pointer to an object of type Foo. Yet s2 will hold a pointer to an object of type Base. s2.content will only point towards an object of type Foo until the save method has finished execution.

Please correct me if I am wrong:

As far as I understand new Foo() creates a pointer to a new object of type Foo. &Foo() on the other hand first creates a new object of type Foo and then points to it.

What exactly is the difference between new Foo() and &Foo() then? Obviously both give you a pointer to an existing object of type Foo.

Why does the object created by new Foo() persist after execution of the save method whereas the object created via &Foo() does not?

May it be that &Foo() creates a temporary object, which will cease to exist after the execution of save? If yes, how can I prolong the life of the object created via &Foo() to make it live (at least) until the destruction of s2?

Edit 1: Thank you very much for the quick answers! I'm simply using Visual Studio, so maybe &Foo() compiling is some Microsoft specific stuff...

like image 688
Domi P. Avatar asked Dec 30 '18 15:12

Domi P.


People also ask

What is the difference between Myobject Foo and Myobject prototype Foo?

They are functionally the same, meaning they will both work the same way, but @ben336 is right; The prototype is used any time an object is created.

What is the difference between object create and new in JavaScript?

The object used in Object. create() actually forms the prototype of the new object, whereas in the new Function() from the declared properties/functions do not form the prototype. You cannot create closures with the Object.

What is the new operator JavaScript?

The new operator lets developers create an instance of a user-defined object type or of one of the built-in object types that has a constructor function.

What does {} mean in JavaScript?

So, what is the meaning of {} in JavaScript? In JavaScript, we use {} braces for creating an empty object. You can think of this as the basis for other object types. Object provides the last link in the prototype chain that can be used by all other objects, such as an Array.


1 Answers

What exactly is the difference between "new Foo()" and "&Foo()" then? Obviously both give you a pointer to an existing object of type Foo.

Why does the object created by "new Foo()" persist after execution of the save method whereas the object created via "&Foo()" does not?


new Foo()

new Foo();

This creates a dynamically-allocated Foo object and returns a pointer pointing to that object. Dynamically-allocated objects will persist until they're explicitly deleted by the programmer:

Foo* foo = new Foo();
delete foo; // delete the object.

&Foo()

Foo();

This creates a Foo object using automatic-storage. This means its lifetime, when the object is deleted, is decided by the scope that the object lives in:

{
  Foo foo{}; // foo lives in automatic storage.
} // end of scope, foo dies

In your case you are creating a new Foo object and you're passing the address of this anonymous object to Storage::save. This object will be destroyed at the end of the full expression. This basically means after s2.save() returns your object will be destroyed and the pointer pointing to it in s2 will be dangling and dereferencing it will be undefined behaviour.


If yes, how can I prolong the life of the object created via "&Foo()" to make it live (at least) until the destruction of s2?

You can't. You probably want a smart pointer here such as std::unique_ptr.


Note that taking the address of a temporary is non-standard and thus this code is non-compliant to begin with. Your compiler is probably using an extension to allow it. MSVC is known for allowing this.

like image 67
Hatted Rooster Avatar answered Sep 28 '22 15:09

Hatted Rooster