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?
Yes, the new operator always allocates memory for the object on the heap. Unlike C++, objects in Java cannot be created on the stack.
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.
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.
You could declare a function called "operator new" inside the Foo class which would block the access to the normal form of new.
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.
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.
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();
}
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?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With