1
votes

I am using pure virtual functions and interfaces for the first time but having some troubles, probably because i did not fully understand some of the basics.

In the main function, i am trying to create an object "a" of a derived class which is creating another object "obj" inside the class and sets a member variable of obj to some value. Later in the main function, i want to print the member variable of obj.

The Error class "AbstractB" has no member "setVar" occurs in DerivedA.h . The setVar function is not part of the abstract class because in different derived classes var may have different data types.

AbstractA.h

class AbstractA
{
public:
    AbstractA() {}
    virtual ~AbstractA() {}

    virtual void buildObj() = 0;
    AbstractB* getObj() { return obj; }

protected:
    AbstractB* obj;
};

AbstractB.h

class AbstractB
{
public:
    AbstractB() {}
    virtual ~AbstractB() {}

    virtual void doSthWithVar() = 0;

    // All derived classes have a private member variable var of varying data types
};

DerivedA.h

 class DerivedA: public AbstractA
 {
 public:
    // buildObj() creates some numbers e.g. 1
    void buildObj() { obj->setVar( 1 ); } // Error due to calling the function using the abstract class instead of the derived one
 };

DerivedB.h

class DerivedB
{
public:
    void setVar( int i ) { var = i; }
    void doSthWithVar(){ std::cout << var << std::endl; }

private:
    int var;
};

main.cpp

int main()
{
    DerivedA a;
    a.buildObj(); // Creating a DerivedB object which is holding a variable var

    // I want to do something like this
    AbstractB* obj = a.getObj();
    obj->doSthWithVar(); // Should print 1
}

Is there any way to call the setVar() function in DerivedA.h to allow later retrieval of var without disturbing the structure of the abstract classes?

EDIT:

I implemented the solution from Robert Andrzejuk in the following way:

class DerivedA: public AbstractA
{
public:
    void buildObj() 
    { 
        DerivedB* b = new DerivedB();
        b->setVar( 1 );
        obj = b;
    }
};
1
A good place to learn good idioms with C++ and Interface style of objects is ATL (think it is going by a different name these days...) There, for example you will be able to discover the "trick" to give the type of the derived class as a template Argument to a base class.BitTickler
How do you expect a to know that its obj should point to a DerivedB, and not an AbstractB?Beta
Thanks for your answers. I have come across the ATL term but never looked into it - probably i should give it a try.C.S.

1 Answers

1
votes

I don't see where You have created an instance of DerivedB?

The most logical place looks like in DerivedA. And that's where You have all the info to call the needed functions.

class DerivedA: public AbstractA
{
   DerivedB b;
public:
   // buildObj() creates some numbers e.g. 1
   void buildObj() 
   { 
        b.setVar( 1 );
        obj = &b; 
   }
};