Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using new operator for copy an object to heap without knowing its type

I have a doubt, the function below can receive an object of type A or something derived type.

A *copyToHeap(A &obj) {
    A *ptr=new A(obj);
    return ptr;
}

If we call it like this:

//B inherits from A
B bObj;
B *hPtr=copyToHeap(bObj);

The object pointed by hPtr is actually of type A or B? Is safe doing this?

like image 709
jlledom Avatar asked Nov 06 '11 11:11

jlledom


People also ask

Where does the new operator in Java allocate memory for a newly created object?

Yes, the new operator always allocates memory for the object on the heap. Unlike C++, objects in Java cannot be created on the stack.

What happens if you call new but the heap is out of memory?

From "New and delete (C++)" on Wikipedia: If not enough memory is available in the free store for an object of type T , the new request indicates failure by throwing an exception of type std::bad_alloc . This removes the need to explicitly check the result of an allocation.

Where is an object created for a class in C++ when created without the new operator?

without new? In C++, we can instantiate the class object with or without using the new keyword. If the new keyword is not use, then it is like normal object. This will be stored at the stack section.

How do you prevent an object from creating heap?

You could declare a function called "operator new" inside the Foo class which would block the access to the normal form of new.


4 Answers

when you do the below in your code:

A* ptr = new A(obj);

you'll always get an A instance. obj will be treated as an A and a new A will get created based on the "A part" of obj.

The better approach is as an earlier reply indicated, add a virtual MakeCopy method to the base class and implement it for the derived classes.

virtual A* MakeCopy();

This method is implemented by making a copy of the object for which its called. It then gets implemented in the derived classes so if you have an A pointer which is actually a B object you'll get a true B copy and avoid the "slicing" which is occurring in your example.

like image 60
Nerdtron Avatar answered Nov 15 '22 20:11

Nerdtron


The returned object is of type pointer to A, which means the object pointed to by hPtr is of type A. It's not safe since calling methods or members exclusive to B will cause a crash or undefined behavior. You're probably looking for the factory pattern.

like image 20
Luchian Grigore Avatar answered Nov 15 '22 21:11

Luchian Grigore


A safe way is to provide a virtual clone method

#include <memory>

class Base
{
public:
    virtual std::unique_ptr<Base> Clone() = 0;
};

class Derived : public Base
{
public:
    Derived(int i) : i_(i)
    {

    }

    std::unique_ptr<Base> Clone()
    {
        return std::unique_ptr<Derived>(new Derived(i_));
    }

private:
    int i_;
};


std::unique_ptr<Base> copyToHeap(std::unique_ptr<Base> obj) 
{
    return obj->Clone();
}
like image 28
hansmaad Avatar answered Nov 15 '22 19:11

hansmaad


It is not safe, it is incorrect, and the compiler should give you some diagnostics. Did you try to compile with g++ -Wall if using GCC?

like image 42
Basile Starynkevitch Avatar answered Nov 15 '22 20:11

Basile Starynkevitch