braaterAfrikaaner
braaterAfrikaaner

Reputation: 1082

Member function not accessible in C++

I have two class hierarchies A and B, where A objects have a pointer to B objects.

class AbstractB{
public:
    AbstractB(){};
    virtual ~AbstractB(){};
    virtual void printVal() = 0;
protected:
    int val;
};

class AbstractA{
public:
    AbstractA(){};
    virtual ~AbstractA(){};
    virtual void printVal() = 0;
protected:
    AbstractB* b;
};

class B1 : public AbstractB{
public:
    B1(): AbstractB(){ val = 1; };
    virtual void printVal(){ std::cout << val; };
    void foo(){ std::cout << "foo"; };
};

class A1 : public AbstractA{
public:
    A1(): AbstractA(){ b = new B1; };
    virtual void printVal(){ b->printVal(); }
    void foo(){ b->foo(); };
};

Compiler complaints about the second to last line "Error: AbstractB has no member "foo". I don't understand this, since I construct a B1 object in the A1 constructor, which has a member foo.

Upvotes: 1

Views: 2945

Answers (3)

Tomasz Kapela
Tomasz Kapela

Reputation: 29

If you want to have specific subclass Bi for each subclass Ai I would sugest to add template class in the middle between AbstractA and A1. This will save you some work and it is safe to use.

class AbstractB{
public:
    AbstractB(){};
    virtual ~AbstractB(){};
    virtual void printVal() = 0;
protected:
    int val;
};

class AbstractA{
public:
    AbstractA(){};
    virtual ~AbstractA(){};
    virtual void printVal() = 0;
};

template<typename BType>
class AbstractAwithPointerTo : public AbstractA{
public:
    AbstractAwithPointerTo(BType * p = 0) : b(p) {}
protected:
    BType * b;
};

class B1 : public AbstractB{
public:
    B1(): AbstractB(){ val = 1; };
    virtual void printVal(){ std::cout << val; }
    void foo(){ std::cout << "foo"; }
};

class A1 : public AbstractAwithPointerTo<B1>{
public:
    A1(): AbstractAwithPointerTo(new B1) {}
    virtual void printVal(){ b->printVal(); }
    void foo(){ b->foo(); };
};

Upvotes: 0

Sqeaky
Sqeaky

Reputation: 1936

The pointer b is of type AbstractB which does not have the foo member function. Even though the only instatiable derived type of AbstractB has a foo member function the parent type does not and if you made other types derived from AbstractB they might not have foo.

I see 3 options:

  1. Add foo to AbstractB.
  2. Make the pointer on A1 a pointer to a B1.
  3. (Please don't) Use some kind of cast in the foo member function on A1.

Upvotes: 0

Tomasz Kapela
Tomasz Kapela

Reputation: 29

Field b is of type AbstractB* and you can only use methods and fields that are present in AbstractB class. In fact b can point to any subclass of AbstractB, not all of them will have foo field.

Upvotes: 2

Related Questions