How to prevent user from destroying an object - c++

I want to return an implementation of a class from a function. The function is in a library. I want to prevent the user from destroying the objects I return. How can I achieve this?
EDIT: Example.
Interface to the world:
class Base
{
public:
virtual void foo() = 0;
};
Base* GetFoo();
Implementation - Internal:
class Bar : public Base
{
public:
void foo() { //Do something}
};
Base* GetFoo()
{
return new Bar
}

You could use a private destructor and create some method (release()) to allow the object to be freed in a controlled manner.
Private destructors
What is the use of having destructor as private?

And to answer your question as you are deriving from base, so you cannot make base destructor private. You can achieve your goal by protected destructor.

Return a shared_ptr<Base> and keep a copy of the pointer yourself. That pointer will keep the object alive, no matter what the user will do with his shared_ptr<Base>. You might even consider returning a weak_ptr<Base> instead, to stress that the lifetime of the object is subject to your whims only.

Why would you want to do that? The user should be getting a copy of the returned object anyway, and it should be up to them whether to allocate or deallocate the copy.

You cannot prohibit the user of your library to shoot himself in a leg while cleaning a loaded gun. I.e. even if you return a constant reference, one could take address from it and then delete it. So you should make your code stable even in this situation.
P.S. private destructors (#nc3b) impose limitations on a further usage of the class (no more local non-dynamic instances, for example), so consider them wisely.

If what you're returning is a new object, then there is no reason why you should need to prevent the user from delete ing it.
However, you shouldn't leave any question about responsibility for deletion. Instead, either use a smart pointer to return the value, or use the polymorphic pImpl pattern (wherein a non-polymorphic wrapper contains a smart pointer to a polymorphic implementation - typically a smart pointer that provides value semantics, such as this ) instead of just returning a derived instance.

Related

Does polymorphism apply on values? Or using move constructor of derived class when returning by (base-)value

I am building some kind of factory method which returns a DerivedClass as a BaseClass in the following way:
BaseClass Factory()
{
return DerivedClass();
}
Am I right, that the move constructor of the BaseClass is used when I call that method:
BaseClass object = Factory();
Since I cannot make the move constructor of the BaseClass virtual, is there an other way to force the move constructor of the DerivedClass to be taken?
Edit1: additional information - I already thought about pointers. But the thing is, I want to export the factory function in a DLL and I wanted to make it as easy as possible for the user. Standard pointers could result in memory leaks and on the other hand not everybody is familiar with smart pointers.
Edit2: As I learnd the real question was: Does polymorphism also work with return by value?
And the answer is NO.
I think you souldn't do:
BaseClass Factory()
But rather
// You'll need to delete
BaseClass* Factory() {
return new Derived();
}
// You will not need to delete
unique_ptr<BaseClass> Factory() {
// return new Derived();
// As the comments point out: prefer use of make_unique
return std::make_unique<Derived>();
}
Otherwise, you're slicing your object.
Polymorphism works only in pointers and references.
In C++, you don't return a derived object as a base class object. That looks like a c# way. You should use pointers.
I am assuming this is something you want.
BaseClass* Factory()
{
return new DerivedClass();
}
Also I never heard about the concept of 'move constructor'.
A plain variable, field, return type, etc. of a base class in C++ cannot contain values of a subclass. This is different from other object-oriented languages such as Java, and it has to do with how the objects are actually represented in memory - storing a polymorphic value requires a pointer or reference. (In Java and similar languages, all object-containing variables are actually pointers to the object which itself is stored elsewhere, so this implementation detail is hidden from the programmer.)
The solution is to use a pointer to allow you to use polymorphism. The naive version of this is to make the function return BaseClass *, and change the return expression to new DerivedClass(), however this leaves you easily open to memory leak bugs, as you must manually ensure that the object is destroyed by the caller when it is no longer needed (via the delete operator). A pereferable solution is to use std::shared_ptr<BaseClass> or std::unique<BaseClass> as the return type, which will ensure that the object is destroyed when a reference to it no longer exists.

Is there a way to get a C++ class to automatically execute a method just before it starts executing the destructor?

Here's a problem scenario: I've got a C++ object that includes a Cleanup() virtual method that needs to be called just before the object is destroyed. In order to do the right thing, this Cleanup method needs access to the fully-formed object (including subclass data), so I can't just call Cleanup() at the start of my own class's destructor, because by the time my class's destructor is called, the destructors any subclasses have already completed and they may have already freed some data that Cleanup() needed to look at.
The obvious solution would be to require the calling code to manually call my routine before deleting the object:
theObject->Cleanup();
delete theObject;
but that solution is fragile, since sooner or later somebody (probably me) will forget to call Cleanup() and bad things will happen.
Another solution would be to have a "holder" object that implements the pImpl technique to wrap the class, and have the holder object's destructor call Cleanup() on the object before deleting the object; but that solution isn't 100% desirable either, since it makes the class work differently from a standard C++ class and makes it impossible to allocate the object on the stack or statically.
So the question is, is there some clever technique (either in C++ or C++11) that I could use to tell the compiler to automatically call a specified (presumably virtual) method on my object before it calls the first subclass-destructor?
(come to think of it, a similar mechanism for automatically calling an Init() method -- just after the last subclass-constructor completes -- might be handy as well)
Lateral thinking: get rid of the Cleanup method, that's what a virtual destructor is for.
The very goal of a virtual destructor is to allow the outmost derived class destructor to be called when delete basepointer; is executed; and as RAII demonstrated, cleanup is the destructor's job.
Now you might argue that you would like an early Cleanup method, to ease the task of the destructor or maybe to reuse the object (kinda like a Reset method in a way). In practice, it rapidly turns into a maintenance nightmare (too easy to forget to clean one field and have state leak from one use to another).
So ask yourself the question: Why not use the destructor for what it's been created for ?
You can use a twist on the PIMPL wrapper:
class PIMPL
{
MyDataThatNeedsInitDestroy object;
public:
PIMPL(Atgs a)
: object(a)
{
object.postCreationInit();
}
~PIMP()
{
object.preDestructionDestory();
}
// All other methods are available via -> operator
MyDataThatNeedsInitDestroy* operator->() { return &object);
};
Yes, this can be done with virtual inheritance, because virtual base subobjects are always constructed (and destroyed) by the most-derived type, and the order of construction (and destruction) of base classes is well-defined also.
Of course, you also may make the delete operator private, and provide a Release() member function consisting of Cleanup(); delete this; But that wouldn't help with stack-allocated objects.
struct B
{
void cleanup()
{
if (!m_bCleanedUp)
{
m_bCleanedUp = true;
...
}
}
virtual B::~B()
{
assert(m_bCleanedUp);
...
}
bool m_bCleanedUp = false;
};
struct D : B
{
D::~D()
{
cleanup(); // if D author forgets, assert will fire
...
}
};
Is there a way to get a C++ class to automatically execute a method just before it starts executing the destructor?
You need to use smart pointer (shared_ptr - available in boost or c++11) with custom deleter instead of raw pointers.
typedef shared_ptr<MyClass> MyClassPtr;
class MyClassDeleter{
public:
void operator()(MyClass* p) const{
if (p)
p->cleanup();
delete p;
}
};
...
MyClassPtr ptr(new MyClass, MyClassDeleter());
--EDIT--
This will work for dynamically allocated objects. There is no solution (I can think of) for stack-allocated objects, so the reasonable action would be to make constructors private and make friend factory method that returns shared_ptr to constructed object - assuming you really need this mechanism.

How do I make an abstract class properly return a concrete instance of another abstract class?

I recently reworked one of my own libraries to try out separating interface from implementation. I am having on final issue with a class that is meant to return an instance of another class.
In the interface definition, I do something like
struct IFoo
{
virtual const IBar& getBar() = 0;
}
and then in the concrete Foo getBar looks like
const IBar& Foo::getBar()
{
Bar ret = Bar();
return ret;
}
The problem is ret gets deleted as soon as getBar is done, causing a big crash when the copy constructor tries to use Bar like so
const Bar myBar = myFoo.getBar();
I have been reading various things, and I know returning by reference is frowned upon, but I do not see any other way (I do not want to return Bar* because I do not want to have to manually delete the return value).
What is the proper way (if any way exists) for an abstract class to return an instance of a concrete class derived from another abstract class?
Note I did see this solution: returning an abstract class from a function
but I do not want to make the return value static and loose thread safety.
Use smart pointers.
These are pointers deleted when not used anymore (see for example http://www.boost.org/doc/libs/1_43_0/libs/smart_ptr/smart_ptr.htm).
You can also return the object by value.
Some compilers provide the Return value optimization which optimize away the copy when returning an object.
Edit:
Sorry. I skimmed through the question and somehow missed the fact that inheritance is involved. Assuming that getBar() can return various kind of IBar returning an IBar pointer makes a lot of sense.
By returning a pointer to base the concrete object is kept intact. The slicing problem is avoided and the original vtbl pointer is available to make virtual function calls. Also (as you noted in your comment) returning an instance of an abstract class is just impossible.
Instead of returning a raw pointer I suggest you return a shared_ptr<IBar> to simplify memory management.
const shared_ptr<IBar> Foo::getBar()
{
shared_ptr<IBar> ret(new Bar());
return ret;
}
Then use it this way:
shared_ptr<IBar> pIBar(foo.getBar());
pIBar->myVirtualFunction();
shared_ptr is the most commonly used smart pointer type in C++0x. If you have a sufficiently recent compiler it will be in the std namespace. Older compiler may have it in the tr1 namespace and it's also part of boost.
You're returning a reference to a local variable. As soon as the function returns the reference, the stack gets popped and that Bar object ceases to exist.
EDIT: I didn't read the whole thing. You'll probably need to use a smart pointer.
Actually, is there any reason why you need to return a base class reference? You could avoid any smart pointer messiness by returning an object of the concrete type itself, since C++ allows covariant return types.
Since you want to transfer ownership of the returned object to the caller, the caller will have to destroy the object. In other words, returning IBar * is your best bet. If you are worried about having to manually call delete, you should look into using a smart pointer package, e.g. boost::shared_ptr.
If you don't want to take care of deletion then you have to use SmartPointers.
In C++ this is the only way to have object "deletes itself" when it is appropriated.
http://en.wikipedia.org/wiki/Smart_pointer
The object that has been created on the stack will be destructed when your stack is removed. The stack is removed when the function exits.
Instead, try something like this:
struct Foo : public IFoo
{
Bar m_Bar;
public:
virtual const IBar& getBar()
{
return m_Bar;
}
}

How to handle 'this' pointer in constructor?

I have objects which create other child objects within their constructors, passing 'this' so the child can save a pointer back to its parent. I use boost::shared_ptr extensively in my programming as a safer alternative to std::auto_ptr or raw pointers. So the child would have code such as shared_ptr<Parent>, and boost provides the shared_from_this() method which the parent can give to the child.
My problem is that shared_from_this() cannot be used in a constructor, which isn't really a crime because 'this' should not be used in a constructor anyways unless you know what you're doing and don't mind the limitations.
Google's C++ Style Guide states that constructors should merely set member variables to their initial values. Any complex initialization should go in an explicit Init() method. This solves the 'this-in-constructor' problem as well as a few others as well.
What bothers me is that people using your code now must remember to call Init() every time they construct one of your objects. The only way I can think of to enforce this is by having an assertion that Init() has already been called at the top of every member function, but this is tedious to write and cumbersome to execute.
Are there any idioms out there that solve this problem at any step along the way?
Use a factory method to 2-phase construct & initialize your class, and then make the ctor & Init() function private. Then there's no way to create your object incorrectly. Just remember to keep the destructor public and to use a smart pointer:
#include <memory>
class BigObject
{
public:
static std::tr1::shared_ptr<BigObject> Create(int someParam)
{
std::tr1::shared_ptr<BigObject> ret(new BigObject(someParam));
ret->Init();
return ret;
}
private:
bool Init()
{
// do something to init
return true;
}
BigObject(int para)
{
}
BigObject() {}
};
int main()
{
std::tr1::shared_ptr<BigObject> obj = BigObject::Create(42);
return 0;
}
EDIT:
If you want to object to live on the stack, you can use a variant of the above pattern. As written this will create a temporary and use the copy ctor:
#include <memory>
class StackObject
{
public:
StackObject(const StackObject& rhs)
: n_(rhs.n_)
{
}
static StackObject Create(int val)
{
StackObject ret(val);
ret.Init();
return ret;
}
private:
int n_;
StackObject(int n = 0) : n_(n) {};
bool Init() { return true; }
};
int main()
{
StackObject sObj = StackObject::Create(42);
return 0;
}
Google's C++ programming guidelines have been criticized here and elsewhere again and again. And rightly so.
I use two-phase initialization only ever if it's hidden behind a wrapping class. If manually calling initialization functions would work, we'd still be programming in C and C++ with its constructors would never have been invented.
Depending on the situation, this may be a case where shared pointers don't add anything. They should be used anytime lifetime management is an issue. If the child objects lifetime is guaranteed to be shorter than that of the parent, I don't see a problem with using raw pointers. For instance, if the parent creates and deletes the child objects (and no one else does), there is no question over who should delete the child objects.
KeithB has a really good point that I would like to extend (in a sense that is not related to the question, but that will not fit in a comment):
In the specific case of the relation of an object with its subobjects the lifetimes are guaranteed: the parent object will always outlive the child object. In this case the child (member) object does not share the ownership of the parent (containing) object, and a shared_ptr should not be used. It should not be used for semantic reasons (no shared ownership at all) nor for practical reasons: you can introduce all sorts of problems: memory leaks and incorrect deletions.
To ease discussion I will use P to refer to the parent object and C to refer to the child or contained object.
If P lifetime is externally handled with a shared_ptr, then adding another shared_ptr in C to refer to P will have the effect of creating a cycle. Once you have a cycle in memory managed by reference counting you most probably have a memory leak: when the last external shared_ptr that refers to P goes out of scope, the pointer in C is still alive, so the reference count for P does not reach 0 and the object is not released, even if it is no longer accessible.
If P is handled by a different pointer then when the pointer gets deleted it will call the P destructor, that will cascade into calling the C destructor. The reference count for P in the shared_ptr that C has will reach 0 and it will trigger a double deletion.
If P has automatic storage duration, when it's destructor gets called (the object goes out of scope or the containing object destructor is called) then the shared_ptr will trigger the deletion of a block of memory that was not new-ed.
The common solution is breaking cycles with weak_ptrs, so that the child object would not keep a shared_ptr to the parent, but rather a weak_ptr. At this stage the problem is the same: to create a weak_ptr the object must already be managed by a shared_ptr, which during construction cannot happen.
Consider using either a raw pointer (handling ownership of a resource through a pointer is unsafe, but here ownership is handled externally so that is not an issue) or even a reference (which also is telling other programmers that you trust the referred object P to outlive the referring object C)
A object that requires complex construction sounds like a job for a factory.
Define an interface or an abstract class, one that cannot be constructed, plus a free-function that, possibly with parameters, returns a pointer to the interface, but behinds the scenes takes care of the complexity.
You have to think of design in terms of what the end user of your class has to do.
Do you really need to use the shared_ptr in this case? Can the child just have a pointer? After all, it's the child object, so it's owned by the parent, so couldn't it just have a normal pointer to it's parent?

Passing a smart pointer as argument inside a class: scoped_ptr or shared_ptr?

I have a class that creates an object inside one public method. The object is private and not visible to the users of the class. This method then calls other private methods inside the same class and pass the created object as a parameter:
class Foo {
...
};
class A {
private:
typedef scoped_ptr<Foo> FooPtr;
void privateMethod1(FooPtr fooObj);
public:
void showSomethingOnTheScreen() {
FooPtr fooObj(new Foo);
privateMethod1(fooObj);
};
};
I believe the correct smart pointer in this case would be a scoped_ptr, however, I can't do this because scoped_ptr makes the class non copyable if used that way, so should I make the methods like this:
void privateMethod1(FooPtr& fooObj);
privateMethod1 doesn't store the object, neither keeps references of it. Just retrieves data from the class Foo.
The correct way would probably be not using a smart pointer at all and allocating the object in the stack, but that's not possible because it uses a library that doesn't allow objects on the stack, they must be on the Heap.
After all, I'm still confused about the real usage of scoped_ptr.
One further possibility is to create the object as a static_ptr for ease of memory management, but just pass the raw pointer to the other private methods:
void privateMethod1(Foo *fooObj);
void showSomethingOnTheScreen() {
scoped_ptr<Foo> fooObj(new Foo);
privateMethod1(fooObj.get());
};
I would use scoped_ptr inside showSomethingOnTheScreen, but pass a raw pointer (or reference) to privateMethod1, e.g.
scoped_ptr<Foo> fooObj(new Foo);
privateMethod1(fooObj.get());
Use here simple std::auto_ptr as you can't create objects on the stack. And it is better to your private function just simply accept raw pointer.
Real usage is that you don't have to catch all possible exceptions and do manual delete.
In fact if your object is doesn't modify object and your API return object for sure you'd better to use
void privateMethod1(const Foo& fooObj);
and pass the object there as
privateMethod1(*fooObj.get());
I'm suspicious about the comment "it uses a library that doesn't allow objects on the stack, they must be on the Heap."
Why? That typically means that they must be deallocated in some special way - so perhaps none of these solutions will work.
In that case, you only have to replace the allocation mechanism.
Create the object on the heap, but pass the object as reference to private methods.
class A {
private:
void privateMethod1(Foo& fooObj);
public:
void showSomethingOnTheScreen() {
scoped_ptr<Foo> fooObj(new Foo);
privateMethod1(*(fooObj.get()));
};
};