无法在C ++中访问成员函数

时间:2018-01-27 03:25:35

标签: c++ polymorphism

我有两个类层次结构A和B,其中A对象具有指向B对象的指针。

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(); };
};

编译器关于倒数第二行的投诉&#34;错误:AbstractB没有成员&#34; foo&#34;。我不明白这一点,因为我在A1构造函数中构造了一个B1对象,它有一个成员foo。

3 个答案:

答案 0 :(得分:2)

字段b的类型为AbstractB *,您只能使用AbstractB类中存在的方法和字段。 事实上,b可以指向AbstractB的任何子类,并非所有子类都有foo字段。

答案 1 :(得分:0)

指针[DDLog addLogger:[DDTTYLogger sharedInstance]]; [DDLog addLogger:[DDASLLogger sharedInstance]]; 的类型为b,但没有AbstractB成员函数。即使foo的唯一可实现派生类型具有AbstractB成员函数,父类型也不会,如果您创建了从foo派生的其他类型,则它们可能没有AbstractB

我看到3个选项:

  1. foo添加到foo
  2. 使AbstractB上的指针指向A1
  3. (请不要)在B1上的foo成员函数中使用某种强制转换。

答案 2 :(得分:0)

如果你想为每个子类Ai设置特定的子类Bi,我会在AbstractA和A1之间的中间添加模板类。 这将为您节省一些工作,使用安全。

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(); };
};