这个c ++继承结构是否可行?

时间:2011-08-25 18:55:09

标签: c++ inheritance

我在很长一段时间内没有使用c ++进行编程,并且想要一些简单的行为,即没有任何虚拟关键字尚未产生:

class Base {
  public:
    int both() { return a(); }
};

class Derived : public Base {
  protected:
    int a();
};

class Problem : public Derived {
};

Problem* p = new Problem();
p.both();

这给了我一个编译时错误。这种行为是否可以用c ++?我只需要前言吗?一切都是虚拟关键词?

6 个答案:

答案 0 :(得分:4)

没有。您必须在a中使用纯虚拟base

class Base {
    virtual int a() = 0;
    int both() {
        return a();
    }
};

答案 1 :(得分:4)

您应该将a()函数声明为Base类中的纯虚方法。

class Base {
    int both() {
        return a();
    }

    virtual int a()=0;
};

然后在a()

中实现Derived方法
class Derived : public Base {
    int a(){/*some code here*/}
};

最后,Problem类没有看到both()方法,因为它在Base中是私有的。设为public

class Base {
public:
    int both() {
        return a();
    }
};

答案 2 :(得分:3)

默认情况下,您的函数both()是私有的。尝试:

class Base {
public:
    int both() {
        // ...

(将来,如果你告诉我们实际的错误信息是什么会有所帮助。)

答案 3 :(得分:2)

您需要在a()中声明class Base,否则编译器不知道如何处理它。

此外,both()目前是私有方法(这是类的默认方法),应该公开,以便从main调用它。

答案 4 :(得分:1)

您的代码中存在多个问题:

  • 除非您声明它们是公共的或受保护的,否则类的元素作为默认值是私有的。
  • 您需要一个虚拟关键字来定义可在父级中调用的虚拟函数。
  • new返回指向问题的指针。

以下是基于测试的完整工作代码:

class Base { 
protected:
virtual int a()=0;
public:
    int both() { 
        return a(); 
    } 
}; 

class Derived : public Base { 
private :
int a()
{
printf("passing through a!");
return 0;
}


}; 

class Problem : public Derived { 
}; 

int main(void)
{
  Problem* p = new Problem(); 
  p->both();
}

CodePad上测试。

答案 5 :(得分:1)

正如其他人所指出的那样,您需要将a()声明为Base的纯虚方法,并将访问权限更改为公开以使您的代码段正常工作。

这是c ++中可能采用的另一种方法:代替虚函数,您可以通过Curiously recurring template pattern使用静态多态:

template <class D>
class Base : public D
{
public: 
    int both() { return D::a(); }
};

class Derived : public Base<Derived> 
{
public:
    int a();
};

我发布这种方法,因为你在c ++中询问可能是什么。在实践中,虚拟方法通常是更好的选择,因为它们具有灵活性。