Best practice on where to delete a resource in an inheritance hierarchy - c++

Consider the following code:
class Base {
protected:
int* ptr_;
public:
virtual ~Base() { /* delete ptr_ ?? */ }
}
class A : public Base {
public:
A() { ptr_ = new int; }
~A() { /* delete ptr_ ?? */ }
}
I'm having a minor dispute with my colleague.
Which destructor should delete ptr_?
I think it should be in A, because it's where it is allocated.
He thinks it should be in Base, because thats where the pointer is.
Please give possible pitfalls why one method is better than the other (if there is one, and it's not just a matter of taste)
EDIT
Alot of people are questioning the design. In practice, the code is much more complicated, and models an Image processing system involving a few cameras.
The role of Base is to manage the resources of the system (A few configurations exist).
Class A and other derived types like it decide the configuration of Base and initialize the system to a specific configuration. I guess now you can ask if Inheritance is the right choice over Composition. A is-a Base, just a specific kind, and that is why we chose inheritance. In this case, ptr_ is a pointer to a specific driver of a camera, which will be decided by the derived type, that is why it is allocated there.

Each class should manage its own resources. When you have multiple derived classes, each one must remember to free the pointer. This is bad, since it duplicates code.
If some derived class is allowed not to assign the pointer a fresh value, then set it to zero in the base class constructor. If some derived class should be allowed to assign to the pointer the address of an automatic variable, then review your design.
Use smart pointers to make the problem totally go away (when I grep delete * in my entire codebase, I find no match :)

The question is one of design more than one of implementation. I tend to agree with your coworker, if the pointer is in the base, it seems to indicate that the base object is responsible for management of the resource, rather than the derived type.
As a matter of fact the bit that is strange is the fact that the derived constructor is modifying a base member, it probably makes more sense to pass the pointer to the base constructor in which case the semantics would be clearer: the base receives a resource during construction and is responsible to manage it during it's lifetime.
If the base should not manage the resource, then why is the pointer at that level? Why is it not a member of the derived type?
Note that when managing a resource, you should consider the rule of the three1: If you have to implement one of copy-constructor, assignment-operator or destructor, then you probably want to implement the three of them (additionally consider implementing a no-throw swap which will be handy).
Once you add copy-constructor and assignment-operator to the mix you will probably see that the natural place to manage the resource is there where it is held.
1 The rule is generic as there are good reasons not to implement all of them always. For example, if you manage your resources inside members that implement RAII (as smart pointers), you might need to provide copy-construction and assignment-operator's as for deep copying semantics, but destruction would not be required. Alternatively, in some contexts you might want to disable *copy-construction* and/or assignments.

In fact, ptr_ should be private! (See Scott Meyers Effective C++, or any primer on object orientation.)
Now, the question doesn’t even pose itself: only the base class can manage its resource. The derived class can only initialise it by passing a request forward to its base (preferably via the constructor):
A() : Base(new int()) { }

I would prefer deleting it in the Base class because,
If I deallocate it in Derived class destructor(which gets called before Base class destructor) then there is a chance that it can get used accidentally in Base class.
Also, The lifetime of the pointer ends within Base class so that should be the place to deallocate it. In fact, I would allocate the pointer within the Base class and not Derived class.
Best is ofcourse to use RAII, and not delte the pointer explicitly, let the Smart pointers take care of deallocating themselves.

You're worrying about code duplication, but I am afraid it clouded your judgement.
I know that DRY get a lot of press (and for good reason) but you misunderstood it. There is a difference between not duplicating code and not duplicating functionality.
DRY is about not duplicating functionality. There might be code patterns that look alike, but are used for different goals, those should not be merged as each goal could shift independently (and un-merging is a nightmare). Their ressemblance is coincidental.
This is the case here. You arbitrarily force a int* ptr_ in the Base (which does not use it) class because surely all derived classes will need it. How do you know that ? At the moment it turns out that all derived classes do need it, but this is a coincidence. They could choose to rely on something else.
Therefore, a sane design is to provide an interface in the base class, and leave it up to each derived class to choose its own implementation:
class Base { public: virtual ~Base() {} };
class D1: public Base {
public:
D1(Foo const& f): ptr_(new Foo(f)) {}
private:
std::unique_ptr<Foo> ptr_;
};
class D2: public Base {
public:
D2(Bar const& f): ptr_(new Bar(f)) {}
private:
std::unique_ptr<Bar> ptr_;
};
On the other hand, if the Base class was to provide some common functionality that required data members, then of course those could be hoisted up in the Base class implementation... though it could be argued this is premature optimization as, once again, some derived classes might choose to do things differently.

ptr_ shouldn't be in the base class because nothing in the base class uses it. It should be in the derived class.
If you must have it there, I agree with you, it should be deleted in the derived classes desteuctor. The base class can't even know if that pointer was even used, why should it delete it?

The best practice is the object that creates the resource should delete the resource - it is their responsibility.

To me the best is to have the same object in charge of the allocation and the unallocation.
So in your code, class A would be in charge of the delete as it performed the new.
But: why did A allocate ptr_ instead of Base? This is the real question here. There's a problem of design to me as ptr_ belongs to Base. Either it should belong to A instead, or Base should be in charge of its memory management.

i would do this, using RAII.
class RaiiResource
{
private:
int* ptr_;
public:
RaiiResource() { ptr_ = new int; }
~RaiiResource() { delete ptr_; }
int* getResource() { return ptr_; }
}
class Base
{
protected:
RaiiResource m_raiiresource;
void anyMethod()
{
int* pIntNeeded = m_raiiresource.getResource();/*when you need the resource*/
}
public:
virtual ~Base() {}
}
class A : public Base {
public:
A() {}
~A() { }
void anyOtherMethod()
{
int* pIntNeededAgain = m_raiiresource.getResource(); /*when you need the resource again somewhereelse*/
}
}
Another way would be using std::shared_ptr that allows managing the scope of life of objects between different objects, which is the case in your case ( Base and A are sharing the need of the object (int) existence)

Related

Using/storing derived member in derived class with base class that stores base member

A situation I often come up against is having a set of classes, Base and Derived, where the Base class has ownership of a base-class member BaseMember, and the Derived class has a reference or pointer to the same object, but as a DerivedMember.
For example, a UI panel class that contains a specific instance of a certain type of control with some special-control functions, inheriting from a general class that contains a general control and has general-control functions.
First, say that BaseMember is inherited by DerivedMemeber.
Without using smart pointers, I might do something like this:
class Base
{
protected:
// receive ownership but only because we say so,
// someone else can still try to delete as it's "just a pointer"
Base(BaseMember* _bmember):
bmember(_bmember)
{}
public:
virtual ~Base()
{
// perform an owner's duty
delete bmember;
}
// functions that might be based on BaseMember + other base state
void SetMemberId(....)
{
bmember->SetId(baz);
}
private:
int baz;
BaseMember* bmember; //owned, but not smartly
}
class Derived: public Base
{
public:
Derived(DerivedMember* _dmember):
Base(_dmember),
dmember(_dmember)
{}
// functions that only make sense for Derived + Derived/Base state
void SetDerivedFrobulation()
{
// only a DerivedMember has frobulation, so only
// Derived allows users to access it
dmember->setFrobulation(foo);
}
private:
int foo; // some state
DerivedMember* dmember; // no ownership here
}
With smart pointers (C++11 and up, specifically, I don't really care about older C++ in this case), I am tempted to do something like this and never let the Base/DerivedMember object out into dumb-pointer-land where it could leak if there was an exception somewhere inconvenient.
class Base
{
protected:
// receive ownership
Base(std::unique_ptr<BaseMember> _member):
member(std::move(_member))
{}
virtual ~Base()
{}
public:
// public access functions here as before
private:
std::unique_ptr<BaseMember> member;
}
class Derived: public Base
{
public:
// pass the ownership down by unique_ptr
Derived(std::unique_ptr<DerivedMember> _dmember):
Base(std::move(_dmember)),
dmember(_dmember.get()) // _dmember is moved! SEGFAULT if access dmember later!
{}
// public access functions here as before
private:
// handy handle to the derived class so we don't need to downcast the base (or even access it!)
DerivedClass* dmember
}
As I noted there, you can't "steal a peek" at the DerivedMember class as it comes in to the Derived constructor, because the unique_ptr is moved away before Derived gets a look in.
I can see a solution in providing a protected access to the BaseMember and static_casting back to DerivedMember in the Derived constructor (i.e. after the Base constructor is done), but this seems an ugly way to get access back to a variable we let slip though our fingers!
Another way could be each inheritor of Base owns the pointer, and base just gets a dumb pointer. In this case, the Base destructor doesn't get access to the member, as it's already gone. Also it would duplicate the ownership logic needlessly.
I think either:
This is symptomatic of an anti-pattern and the design of the whole Base/Derived/BaseMember/DerivedMember system is not good practice.
I'm missing a trick and there is a clean way to do this without fumbling a smart pointer and making a leak possible or adding functions and exposing interfaces or casting too much.
Is this a good pattern for re-use, or should I look elsewhere?
Expanding on the use case (EDIT)
In a core library, I have a class DataInterpreter which shows "some interpretation" of data - could be a string, an image, etc. This is then inherited by, amongst others, TextInterpreter which presents a string.
I then have a DataDisplayPanel class which represents a piece of UI for displaying in an abstract sense. Exactly what is in this panel will depend on the interpreter used: a TextInterpreter should get a text entry field and say a button to set some text display option, and that is handled in TextDisplayPanel, which has "special" knowledge of the text aspect of the interpreter.
There is then a DataAggregatePanel which combines a number of DataDisplayPanels and provides some global settings that affect all displays (via virtual functions), and manages the panels in a std::vector<std::unique_ptr<DataDisplayPanel> >. This aggregate class doesn't deal with any of the derived classes at all, any functions would be polymorphic and defined in the base.
In the application (which depends on the core library), these classes are extended (by inheritance or composition, whichever makes more sense). For example, if the application is a WX GUI, I might have wxDataAggregatePanel which contains wxTextDisplayPanel (and others), all of which are wxPanels. In this case, wxTextDisplayPanel might own a wxTextEntry and either own or inherit TextInterpreter and use its knowledge of the TextInterpreter's specific methods to fill the text box with a string.
You may use delegating constructor:
class Derived: public Base
{
public:
Derived(std::unique_ptr<DerivedMember> _dmember):
Derived(_dmember, _dmember.get())
{}
// public access functions here as before
private:
Derived(std::unique_ptr<DerivedMember>& _dmember, DerivedMember* ptr):
Base(std::move(_dmember)),
dmember(ptr)
{}
private:
// handy handle to the derived class so we don't need to downcast the base (or even access it!)
DerivedClass* dmember
};

Gradually construct an object

Suppose there is a hierarchy of two classes (class Derived: public Base). Both these classes have big memory footprint and costly constructors. Note that nothing in these classes is allocated in heap: they just have a big sizeof.
Then there is a function with a fast path (executed always) and a slow path (executed conditionally). Fast path needs a Base instance, and slow path needs a Derived instance constructed from existing base. Also, slow path decision can be made only after the fast path.
Current code looks like this:
void f()
{
Base base;
/* fast path */
if (need_slow_path) {
Derived derived (base);
/* slow path */
}
}
This is inefficient, because the base needs to be copied into derived; also the base is allocated twice and there is a risk of overflowing the stack. What I want to have:
allocate memory for Derived instance
call Base ctor on it
execute the fast path
if needed, call Derived ctor on the existing Base instance and execute the slow path
Is it possible in C++? If not, what are possible workarounds? Obviously, I'm trying to optimize for speed.
I am afraid this is not possible just as you wrote - any constructor of Derived must call a constructor of the Base subobject, so the only way to do that legally would be to call Base's destructor first, and I believe you don't want that.
However, it should be easy to solve this with a slight redesign - prefer composition over inheritance, and make Derived a separate class that will store a reference (in the general sense; it can of course be a pointer) to Base and use it. If access control is an issue, I feel a friend is justified here.
You should change your design slightly to change your reliance on inheritance to that on composition.
You could encapsulate members of derived class (not present in the base class) into another class, and keep it's null reference in the derived class.
Now directly initialize derived class without initializing new class's object.
Whenever slow path is required, you can initialize and use it.
Benefits
Inheritance relationship between derived and base class is preserved.
Base class object is never copied.
You have lazy initialization of derived class.
I can fake it.
Move/all the data of derived into an optional (be it boost or std::ts::optional proposal for post C++14, or hand rolled).
Iff you want the slow path, initialize the optional. Otherwise, leave it as nullopt.
There will be a bool overhead, and checks when you assign/compare/destroy implicit. And things like virtual functions will be derived (ie, you have to manage dynamic dispath manually).
struct Base {
char random_data[1000];
// virtual ~Base() {} // maybe, if you intend to pass it around
};
struct Derived:Base {
struct Derived_Data {
std::string non_trivial[1000];
};
boost::optional< Derived_Data > m_;
};
now we can create a Derived, and only after we m_.emplace() does the Derived_Data get constructed. Everything still lives is in one contiguous memory block (with a bool injected by the optional to track if m_ was constructed).
Not sure if you can do exacactly what you want i.e execute "fast" path before second contructor but i think you use 'placement new' feature - manually call contructors based on need_slow_path predicate. i.e but that changes flow a little:
allocate memory for Derived instance
call Base or Derived ctor on it
execute the fast path
execute the slow path (if needed(
The example code
#include <memory>
void f(bool need_slow_path)
{
char bufx[sizeof(Derived)];
char* buf = bufx;
Derived* derived = 0;
Base* base = 0;
if (need_slow_path ) {
derived = new(buf) Derived();
base = derived;
} else {
base = new(buf) Base();
}
/* fast path using *base */
if (need_slow_path) {
/* slow path using *base & * derived */
}
// manually destroy
if (need_slow_path ) {
derived->~Derived();
} else {
base->~Base();
}
}
Placement new is well described here: What uses are there for "placement new"?
Can you define move copy con't in your compiler ?
There is an excellent explanation (although a bit long ) here
https://skillsmatter.com/skillscasts/2188-move-semanticsperfect-forwarding-and-rvalue-references
I don't have experience with move semantics so I might be wrong but since you want to avoid coping the base object when passing it to the derived class move semantics should do the trick
First extract constructor code into initializing methods both for Base and Derived.
Then I would make the code similar to this:
void f()
{
Derived derived;
derived.baseInit();
/* fast path */
if (need_slow_path) {
derived.derivedInit();
/* slow path */
}
}
It's a good idea to extract classes and use composition as Tanmay Patil suggested in his answer.
And yet another hint: If you haven't done already, dive into Unit-Tests. They will help you dealing with huge classes.
Perhaps instead of a class and constructors, you need a plain-old-struct and initialization functions here. You’ll be giving up a lot of the C++ conveniences, of course, but you’ll be able to implement your optimization.

Is it ever a good idea to put virtual methods on a copyable type?

Have seen some related questions, but not this exact one...
I've treated classes as fitting into a few major categories, let's say these four for simplicity:
Value Classes which have some data and a bunch of operations. They can be copied and meaningfully compared for equality (with copies expected to be equal via ==). These pretty much always lack virtual methods.
Unique Classes whose instances have identity that you disable assignment and copying on. There's usually not an operator== on these because you compare them as pointers, not as objects. These quite often have a lot of virtual methods, as there isn't risk of object-slicing since you're being forced to pass them by pointer or reference.
Unique-but-Clonable Classes which disable copying, but are pre-designed to support cloning if that's what you really want. These have virtual methods, most importantly those following the virtual construction / cloning idiom
Container Classes which inherit the properties of whatever they're holding. These tend not to have virtual methods...see for instance "Why don't STL containers have virtual destructors?".
Regardless of holding this informal belief system, a couple times I've tried adding a virtual method to something copyable. While I may have thought it would "be really cool if that worked", inevitably it breaks.
This led me to wonder if anyone has an actual good example of a type which has virtual methods and doesn't disable copying?
The only counter-example that I have are classes that are meant to be stack-allocated and not heap-allocated. One scheme I use it for is Dependency Injection:
class LoggerInterface { public: virtual void log() = 0; };
class FileLogger final: public LoggerInterface { ... };
int main() {
FileLogger logger("log.txt");
callMethod(logger, ...);
}
The key point here is the final keyword though, it means that copying a FileLogger cannot lead to object-slicing.
However, it might just be that being final turned FileLogger into a Value class.
Note: I know, copying a logger seems weird...
There's nothing inherently wrong in being able to copy a polymorphic class. The problem is being able to copy a non-leaf class. Object slicing will get you.
A good rule of thumb to follow is never derive from a concrete class. This way, non-leaf classes are automatically non-instantiable and thus non-copyable. It won't hurt to disable assignment in them though, just to be on the safe side.
Of course nothing is wrong with copying an object via a virtual function. This kind of copying is safe.
Polymorphic classes are normally not "value-classes" but it does happen. std::stringstream comes to mind. It'not copyable, but it is movable (in C++11) and moving is no different from copying with regard to slicing.
Virtual dispatch happens a runtime. The only reason one should want it is when the actual, dynamic type of an object cannot be known until runtime. If you already knew the desired dynamic type when writing the program, you could use different, non-virtual techniques (such as templates, or non-polymorphic inheritance) to structure your code.
A good example for the need for runtime typing is parsing I/O messages, or handling events – any kind of situation where one way or another you'll either have some sort of big switch table to pick the correct concrete type, or you write your own registration-and-dispatch system, which basically reinvents polymorphism, or you just use virtual dispatch.
(Let me interject a warning: Many people misuse virtual functions to solve problems that don't need them, because they're not dynamic. Beware, and be critical of what you see.)
With this said, it's now clear that your code will be dealing mostly with the polymorphic base classes, e.g. in function interfaces or in containers. So let's rephrase the question: Should such a base class be copyable? Well, since you never have actual, most-derived base objects (i.e. the base class is essentially abstract), this isn't really an issue, and there's no need for this. You've already mentioned the "clone" idiom, which is the appropriate analogue of copying in a polymorphic.
Now, the "clone" function is necessarily implemented in every leaf class, and it necessarily requires copying of the leaf classes. So yes, every leaf class in a clonable hierarchy is a class with virtual functions and a copy constructor. And since the copy constructor of a derived class needs to copy its base subobjects, all the bases need to be copyable, too.
So, now I believe we've distilled the problem down to two possible cases: Either everything in your class hierarchy is completely uncopyable, or your hierarchy supports cloning, and thus by necessity every class in it is copyable.
So should a class with virtual functions have a copy constructor? Absolutely. (This answers your original question: when you integrate your class into a clonable, polymorphic hierarchy, you add virtual functions to it.)
Should you try to make a copy from a base reference? Probably not.
Not with a single, but with two classes:
#include <iostream>
#include <vector>
#include <stdexcept>
class Polymorph
{
protected:
class Implementation {
public:
virtual ~Implementation() {};
// Postcondition: The result is allocated with new.
// This base class throws std::logic error.
virtual Implementation* duplicate() {
throw std::logic_error("Duplication not supported.");
}
public:
virtual const char* name() = 0;
};
// Precondition: self is allocated with new.
Polymorph(Implementation* self)
: m_self(self)
{}
public:
Polymorph(const Polymorph& other)
: m_self(other.m_self->duplicate())
{}
~Polymorph() {
delete m_self;
}
Polymorph& operator = (Polymorph other) {
swap(other);
return *this;
}
void swap(Polymorph& other) {
std::swap(m_self, other.m_self);
}
const char* name() { return m_self->name(); }
private:
Implementation* m_self;
};
class A : public Polymorph
{
protected:
class Implementation : public Polymorph::Implementation
{
protected:
Implementation* duplicate() {
return new Implementation(*this);
}
public:
const char* name() { return "A"; }
};
public:
A()
: Polymorph(new Implementation())
{}
};
class B : public Polymorph {
protected:
class Implementation : public Polymorph::Implementation {
protected:
Implementation* duplicate() {
return new Implementation(*this);
}
public:
const char* name() { return "B"; }
};
public:
B()
: Polymorph(new Implementation())
{}
};
int main() {
std::vector<Polymorph> data;
data.push_back(A());
data.push_back(B());
for(auto x: data)
std::cout << x.name() << std::endl;
return 0;
}
Note: In this example the objects are copied, always (you may implement shared semantics, though)

Dealing with protected/private constructor/destructor for a CRTP design?

Consider the following code:
#include <iostream>
#include <type_traits>
// Abstract base class
template<class Crtp>
class Base
{
// Lifecycle
public: // MARKER 1
Base(const int x) : _x(x) {}
protected: // MARKER 2
~Base() {}
// Functions
public:
int get() {return _x;}
Crtp& set(const int x) {_x = x; return static_cast<Crtp&>(*this);}
// Data members
protected:
int _x;
};
// Derived class
class Derived
: public Base<Derived>
{
// Lifecycle
public:
Derived(const int x) : Base<Derived>(x) {}
~Derived() {}
};
// Main
int main()
{
Derived d(5);
std::cout<<d.set(42).get()<<std::endl;
return 0;
}
If I want a public inheritance of Derived from Base, and if I don't want a virtual destructor in the base class, what would be the best keywords for the constructor (MARKER 1) and the destructor (MARKER 2) of Base to guarantee that nothing bad can happen ?
Whatever programming style you use, you can alwyas do something bad: even if you follow the best of the bestest guideline practice. That's something physical behind it (and relate to the impossibility to reduce the global entrophy)
That said, don't confuse "classic OOP" (a methodology) with C++ (a language), OOP inheritache (a relation) with C++ inheritance (an aggregation mechanism) and OOP polymorphism (a model) with C++ runtime and static polymorphism (a dispatching mechanism).
Although names sometime matches, the C++-things don't have to necessarily sevicing OOP-things.
Public inheritance from a base with some non-virtual methods is normal. and destructor is not special: just dont call delete on the CRTP base.
Unlike with classic OOP, a CRTP-base has different type for each of the deriveds, so having a "pointer to a base" is clueless since there is no "pointer to a common type". And hence the risk to call "delete pbase" is very limited.
The "protected-dtor paradigm" is valid only if you are programming OOP-inheritance using C++ inheritance for object managed (and deleted) though pointer-based polymorphism. If you are following other paradigms, those rules should not be treated in a literal way.
In your case, the proteced-dtor just deny you to create a Base<Derived> on the stack and to call delete on a Base*. Something you will never do, since Base with no "Dervied" has no sense to exist, and having a Base<Derived>* makes no sense since you can have just a Derived*, hence having both public ctor and dtor makes no particular mess.
But you can even do the opposite choice to have both ctor and dtor protected, since you will never construct a Base alone, since it always needs a Derived type to be known.
Because of the particular construction of CRTP, all the classical OOP stuff leads to a sort of "indifferent equilibrium", since there is no more the "dangerous usecase".
You can use them or not, but no particular bad-thing can happen. Not if you use object the way they had been designed to be used.
While your code works I find it odd to mark the destructor rather than the constructor as protected. Normally my reasoning would be that you want to prevent the programmer from accidentally creating a CRTP base object. It all comes down to the same of course, but this is hardly canonical code.
The only thing that your code prevents is the accidental deletion of a CRTP object via a base pointer – i.e. a case like this:
Base<Derived>* base = new Derived;
delete base;
But that is a highly artificial situation that won’t arise in real code since CRTP simply isn’t supposed to be used that way. The CRTP base is an implementation detail that should be completely hidden from the client code.
So my recipe for this situation would be:
Define a protected constructor.
Don’t define a destructor – or, if required for the CRTP semantic, define it as public (and non-virtual).
There's no problem, since the destructor is protected it means that client code can't delete a pointer to Base, so there's no problem with Base's destructor being non-virtual.

Returning abstract datatypes in C++ without dangling pointers

Hallo,
I come from a C# background and don't have a lot of C++ experience. To produce clean code I try to separate implementation and interfaces and use inheritance when possible. And when I tried to apply typical C# concepts to C++ I ran into a problem that I've been unable to resolve so far. I assume that this is probably trivial for an experienced C++ programmer but it has been driving me crazy for quite a while.
First I declare a base class (it contains no logic at the moment but it will in the future)
class PropertyBase : public IProperty
{
};
Then I define an interface for the Properties
class IProperty
{
public:
virtual ~IProperty() {};
virtual PropertyBase correct(const ICorrector &corrector) = 0;
virtual PropertyBase joinWith(const PropertyBase &partner, const IRecombinator &recombinator) = 0;
};
This is where the problem comes in: The compiler returns errors for the two virtual functions saying that it is not allowed to declare a function that returns an abstract class. Of course I don't want to return an object of the type PropertyBase. I want to declare other classes that inherit from PropertyBase that return an instance of themselves.
Now I've read that a possible way around it is to modify IProperty like this to return pointers:
class IProperty
{
public:
virtual ~IProperty() {};
virtual PropertyBase* correct(const ICorrector &corrector) = 0;
virtual PropertyBase* joinWith(const PropertyBase &partner, const IRecombinator &recombinator) = 0;
};
However I would like to avoid this if possible to prevent memory leaks. It would be great if someone would have a better idea to deal with this problem.
Thank you very much
If you're afraid of memory leaks, switch to smart pointers. That has the additional benefit of being self-documenting wrt. ownership of the returned object.
class IProperty
{
public:
virtual ~IProperty() {};
virtual std::unique_ptr<PropertyBase> correct(const ICorrector &) = 0;
virtual std::unique_ptr<PropertyBase> joinWith(const PropertyBase &,
const IRecombinator &) = 0;
};
In your client code:
std::unique_ptr<PropertyBase> pb(property.correct(corrector));
// use pb and forget about it; smart pointers do their own cleanup
Or, if you want reference counting on the object:
std::shared_ptr<PropertyBase> pb(property.correct(corrector));
See MSDN docs for unique_ptr, shared_ptr.
This may not be the answer you're looking for, but it seems to me that you are a little confused about pointers and values in C++.
You have to return either a pointer, or a reference, in C++ if you want proper ad-hoc polymorphism. In this case, the compiler issued an error, because the base class was abstract. If instantiating an abstract class would be possible, it would have "holes" in it.
The thumb rule is: Whenever you have a class hierarchy, never return objects of such types by value. Suppose you have class Base { int x; }, and class Derived : public Base { int y; }. If you do this:
Base Function() { Derived d; return d; }
...
Base b = Function();
Then b will not be a value of class Derived "hiding behind" a Base. The value b WILL be Base. The compiler will "slice off" the differences between Derived and Base, and put it into b.
In C++, you will have to use pointers or references to facilitate ad-hoc polymorphism. References in C# is pretty much the same thing as pointers in C++, with the exception that you do not have to free the objects in C#, as the garbage collector will handle this for you.
There's nothing wrong with returning a pointer to an object. If you're worried about memory leaks, as you should be, the solution is to use smart pointers to store the returned pointer. The most flexible of these is shared_ptr from boost or the upcoming C++0x standard.
More generally, if you're going to be doing any serious amount of work in C++, getting comfortable with pointers and memory management is kind of essential. For in-depth coverage of that and other tricky aspects of C++, I strongly recommend the Effective C++ books by Scott Meyers and the Exceptional C++ books by Herb Sutter.
There is very easy solution to this problem. Use pointers or references for return values, but instead of returning ownership in the pointers, you should not return ownership.
For example:
class A : public Base
{
public:
Base *correct(const I &c)
{ p2 = do_something(c); return &p2; }
...
private:
A2 p2;
};
What makes this work is that you store the p2 inside the class and never pass ownership of the objects to outside of it. The function in the interface will not create new objects, but instead it'll just return existing one, configured to correct state based on function's parameters. This is a good alternative to the unique_ptr and shared_ptr solution which relies on heap allocation and creating new objects and passing them around.
Now the nice trick with this is that you need to list all possible types you want to return from your correct() function in the data members of the class. For example, if sometimes you would return different type, it'd look like this:
class B : public Base
{
public:
Base *correct(const I &c) {
switch(c.get_bool()) {
case false: p3 = do_something_else(c); return &p3;
case true: p4 = do_something(c); return &p4;
};
}
private:
B3 p3;
B4 p4;
};
But placing your objects p3 and p4 inside the current B object will solve this problem completely.