Reputation: 1082
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
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
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:
foo
to AbstractB
.A1
a pointer to a B1
.A1
.Upvotes: 0
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