【问题标题】:Base class is abstract, and derived is also abstract? [closed]基类是抽象的,派生也是抽象的? [关闭]
【发布时间】:2012-05-21 04:36:33
【问题描述】:

我有基类:

class CDigit
{
private:
int m_iDigit;
public:
CDigit() 
{
    m_iDigit = 0;
}
CDigit( const int digit ) 
{
    m_iDigit = digit;
}
void setDigit( const int digit )
{
    m_iDigit = digit;
}
int getDigit() const
{
    return m_iDigit;
}
virtual void output(ostream &x) = 0;
virtual bool less( CDigit *pDigit ) = 0;
};

还有派生类

class CExpected : public CDigit
{
private:
int m_iExpFreq;
public:
CExpected() : CDigit()
{
    m_iExpFreq = 0;
}
CExpected( const int dig, const int freq) : CDigit(dig)
{
    m_iExpFreq = freq;
}
CExpected( const CExpected& ce)
{
    m_iExpFreq = ce.m_iExpFreq;
    this->setDigit( ce.getDigit() );
}
    void output(ostream &x)
{
    x<<this->getDigit()<<" "<<this->m_iObsFreq;
}
bool less( CObserved *pDigit )
{
    if( ( pDigit->getDigit() == this->getDigit() ) && (pDigit->getObserved() == this->getObserved() ) )
        return true;
    else
        return false;
}
...
};

问题是编译器告诉我 CExpected 是一个抽象类,我无法实例化它。我做错了什么?

编辑:我已经实现了它们,但没有在此处添加它们

【问题讨论】:

  • 是的,因为您没有在派生类中定义纯虚方法(outputless)。
  • 我做了但没有错误地添加它们:(对不起
  • 在不相关的注释中,从不为您的类添加前缀 C(或任何相关前缀)是有意义的。这个“约定”源于一个误解,仅此而已(微软在他们的编译器还不理解命名空间时使用它,以消除与其他类的歧义;但即便如此,它也不是每个人都可以使用,以免消除歧义丢失)。
  • 此外,具有if (…) return true; else return false; 形式的代码也没有意义,而且风格不好。只需将其替换为return …;
  • 我的任务需要这样命名。很高兴知道。

标签: c++ oop inheritance


【解决方案1】:

您尚未实现outputless。任何没有定义纯虚函数的类都不能被实例化。

一个好的编译器应该给你更好的信息:

test.cpp: In function ‘int main(int, char**)’:
test.cpp:53: error: cannot declare variable ‘c’ to be of abstract type ‘CExpected’
test.cpp:32: note:   because the following virtual functions are pure within ‘CExpected’:
test.cpp:27: note:  virtual void CDigit::output(std::ostream&)
test.cpp:28: note:  virtual bool CDigit::less(CDigit*)

如果你想让它们成为可选的,不要使用= 0 说明符,它表示虚方法(并且是抽象类的标记)。

【讨论】:

  • 纯虚拟,而不仅仅是虚拟。
  • 是的。谢谢并更新。
【解决方案2】:

在这种情况下,签名不同:

virtual bool less( CDigit *pDigit ) = 0;
virtual bool less( CObserved *pDigit )

(除非 CObserved 被定义为 CDigit)

问题在于类型不同,如果派生,它不能匹配以多态调用,因为您希望得到提升——这是无效的。您在CExpected 中的定义需要匹配,并声明为:

virtual bool less( CDigit *pDigit ) { ... }

【讨论】:

    猜你喜欢
    • 2020-06-07
    • 1970-01-01
    • 1970-01-01
    • 2012-04-22
    • 2014-04-25
    • 1970-01-01
    • 2017-06-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多