Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 270
Compuholic Avatar asked Apr 19 '11 18:04

Compuholic


People also ask

How can we avoid dangling pointer?

The dangling pointer errors can be avoided by initializing the pointer to the NULL value. If we assign the NULL value to the pointer, then the pointer will not point to the de-allocated memory. Assigning NULL value to the pointer means that the pointer is not pointing to any memory location.

What is dangling pointers in C?

A dangling pointer is a pointer that occurs at the time when the object is de-allocated from memory without modifying the value of the pointer. A void pointer is a pointer that can point to any data type. It points to the deleted object. A void pointer can be assigned the address of any data type.

Can you delete a dangling pointer?

Yes, performing delete on a dangling pointer can lead to issues: ... The delete operator must be used only with a valid pointer previously allocated by using new. Using any other type of pointer with delete is undefined and will almost certainly cause serious problems, such as a system crash.

Does C++ have dangling pointers?

As the world's leading example of an object-oriented programming language that does not rely on garbage collection, C++ makes it easy to create dangling pointers.


1 Answers

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.

like image 176
Fred Foo Avatar answered Sep 20 '22 10:09

Fred Foo