JuliusCaesar
JuliusCaesar

Reputation: 351

C++ use interfaces without dynamic allocation

I'm trying to work with interfaces

class IDemo
{
    public:
        virtual ~IDemo() {}
        virtual uint32_t Some_Operation(uint32_t a, uint32_t b) = 0;
};





class Child_A : public IDemo
{
    public:
        virtual uint32_t Some_Operation(uint32_t a, uint32_t b);
};



class Child_B : public IDemo
{
    public:
        virtual uint32_t Some_Operation(uint32_t a, uint32_t b);
};

Child_A::Some_Operation returns the sum of a+b Child_B::Some Operation return the product a*b

The usage is as follows

bool Test_Inferface()
{

    IDemo* pDemo = new Child_B();

    uint32_t product = pDemo->Some_Operation(1, 2);

    delete pDemo;

    if (2 != product)
    {
        return false;
    }


    pDemo = new Child_A();

    uint32_t sum = pDemo->Some_Operation(1,2);

    delete pDemo;

    if(3 != sum)
    {
        return false;
    }

    return true;
}

I'm trying to avoid new/delete because of possible memory leaks. Is it possible to statically allocate the interface?

IDemo test = Child_A();

The compiler does not like that.

Upvotes: 0

Views: 945

Answers (3)

ADG
ADG

Reputation: 333

IDemo is not an interface, it's an abstract base class. Your choice of naming convention suggests you come from a C# background. You should be aware of an important difference between C#/Java interfaces and C++ abstract base classes. It is common for a C#/Java class to implement multiple interfaces, it is also possible to do something similar with C++ abstract (or concrete) classes. Before doing so you should be aware of the diamond inheritance problem. See the following stack overflow question.

Multiple Inheritance from two derived classes.

To answer your original question don't include the compiler error message for the declaration:

IDemo test = Child_A();

But what you are trying to do is declare a concrete instance of an abstract base class and assign an instance of a derived class to it. That is not valid C++, nor does it make any sense. If you are using an abstract base class you are trying to take advantage of polymorphism. In C++ that means a base type pointer or reference to a derived class.

You could use:

const IDemo& test = Child_A();

This would require any methods on IDemo to be declared const and isn't an approach I would recommend since talking a reference to a temporary or short lived object can lead to problems e.g. if you assign test to a reference with a longer lifetime than the scope of the function (e.g. by returning it), your program will crash.

Upvotes: 0

Galik
Galik

Reputation: 48635

It is very simple. Polymorphism (interfaces) have nothing to do with dynamic allocation. If you don't want to dynamically allocate, then don't.

Your example works easily like this:

bool Test_Inferface()
{

    Child_B child_b;

    uint32_t product = child_b.Some_Operation(1, 2);

    if (2 != product)
    {
        return false;
    }


    Child_A chile_a;

    uint32_t sum = child_a.Some_Operation(1,2);

    if(3 != sum)
    {
        return false;
    }

    return true;
}

You may need a better example that actually uses interfaces.

// here we have an interface reference parameter that doesn't care if what is
// passed to it is dynamically allocated or sitting on the stack.
uint32_t better_example(IDemo& demo)
{
    return demo.Some_Operation(1, 2);
}

bool Test_Inferface()
{

    Child_B child_b;

    uint32_t product = better_example(child_b);

    if (2 != product)
    {
        return false;
    }


    Child_A chile_a;

    uint32_t sum = better_example(child_a);

    if(3 != sum)
    {
        return false;
    }

    return true;
}

Upvotes: 3

M.M
M.M

Reputation: 141648

You can write:

Child_B b{};
IDemo *pDemo = &b;

and proceed as before (don't delete pDemo though).

If you want to destroy b at a certain point then use braces to introduce a declarative region.

Upvotes: 1

Related Questions