C++ C++;派生类是抽象错误
我在Dialin中遇到了一个问题,派生类是抽象的。我不知道为什么,因为我拥有的唯一虚拟函数具有相同的参数和相同的返回类型。据我所知,这是唯一的限制,但显然我错了 这是我的密码: 标题:C++ C++;派生类是抽象错误,c++,inheritance,virtual,abstract-class,C++,Inheritance,Virtual,Abstract Class,我在Dialin中遇到了一个问题,派生类是抽象的。我不知道为什么,因为我拥有的唯一虚拟函数具有相同的参数和相同的返回类型。据我所知,这是唯一的限制,但显然我错了 这是我的密码: 标题: class Event{ class ModemSimV2; public: Event( ); Event( const Event &e ); ~Event( ); virtual void process( ModemSimV2 &m ) = 0;
class Event{
class ModemSimV2;
public:
Event( );
Event( const Event &e );
~Event( );
virtual void process( ModemSimV2 &m ) = 0;
protected:
int who; // the number of the user
int time; // when the event will occur
int what; // DIAL_IN or HANGUP
};
class Dialin : public Event{
class ModemSimV2;
public:
Dialin( int name = 0, int tm = 0 );
Dialin( const Dialin &d );
~Dialin( );
virtual void process( ModemSimV2 &m );
private:
int who;
int time;
int what;
};
资料来源:
Event::Event(){
}
Event::Event( const Event &e ) {
*this = e;
}
Event::~Event( ) {
}
Dialin::Dialin (int name, int tm )
: time( tm ), who( name ) {
return;
}
Dialin::Dialin ( const Dialin &d ) {
*this = d;
}
Dialin::~Dialin( ) {
}
void Dialin::process( ModemSimV2 &m ) {
}
问题是名为
ModemSimV2
的类有两种不同的转发声明:
Event::ModemSimV2 // These are different classes
Dialin::ModemSimV2 // with the same unqualified name.
在事件
中,过程()的签名是:
virtual void process( Event::ModemSimV2 &m ) = 0;
在Dialin
中process()的定义实际上是:
virtual void process( Dialin::ModemSimV2 &m );
因此,在事件中声明的纯虚拟函数没有在拨号中实现问题是名为ModemSimV2
的类有两种不同的前向声明:
Event::ModemSimV2 // These are different classes
Dialin::ModemSimV2 // with the same unqualified name.
在事件
中,过程()的签名是:
virtual void process( Event::ModemSimV2 &m ) = 0;
在Dialin
中process()的定义实际上是:
virtual void process( Dialin::ModemSimV2 &m );
因此,在事件
中声明的纯虚拟函数没有在拨号
中实现。另一方面,您没有将~Event
声明为虚拟
,这通常是一件坏事。哦,是的,谢谢。我现在从我的讲座中记起了这一点。在Linux上使用GCC4.4.3为我编译。有3个警告,但没有一个与纯虚拟函数有关。@dbv:您是否尝试实例化拨号
?定义抽象类不会产生错误,但实例化它会产生错误。@dbv:在您尝试实例化拨号之前,它可以正常编译。定义一个虚拟类很好,但不能实例化它。然而,对于编译器所知道的一切,您可以打算使用拨号
作为某个进一步派生类的基础(尽管由于事件::ModelSimV2
是私有的,进一步派生类也无法重写虚拟类)。另一方面,您没有将~Event
声明为虚拟
,这通常是件坏事。哦,是的,谢谢你。我现在从我的讲座中记起了这一点。在Linux上使用GCC4.4.3为我编译。有3个警告,但没有一个与纯虚拟函数有关。@dbv:您是否尝试实例化拨号
?定义抽象类不会产生错误,但实例化它会产生错误。@dbv:在您尝试实例化拨号之前,它可以正常编译。定义一个虚拟类很好,但不能实例化它。然而,对于编译器所知道的一切,您可以打算使用Dialin
作为某个进一步派生类的基础(尽管由于Event::ModelSimV2
是私有的,因此进一步派生类也无法覆盖虚拟类)。+1。是的,它们是两个不同的类,这意味着,Dialin
并没有真正定义基类的纯虚函数,而是添加了一个新的虚函数。@Nawaz,是的。这就是我要表达的意思。这是一个新的C++11override
属性非常有用的地方——编译器会直接告诉您(即,在错误消息中),正如它所定义的,Dialin::process
不会覆盖任何内容。因此,解决方案是将ModemSimV2
的正向decl移到相应类之外。@Robᵩ: 是的,通常。另一种方法是在事件
中保护它,而不是在拨号
中重新声明它(并且在某个地方提供了事件::ModelSimV2
的实现)。如果它真的是::ModelSimV2
,那么您就完全正确了。+1。是的,它们是两个不同的类,这意味着,Dialin
并没有真正定义基类的纯虚函数,而是添加了一个新的虚函数。@Nawaz,是的。这就是我要表达的意思。这是一个新的C++11override
属性非常有用的地方——编译器会直接告诉您(即,在错误消息中),正如它所定义的,Dialin::process
不会覆盖任何内容。因此,解决方案是将ModemSimV2
的正向decl移到相应类之外。@Robᵩ: 是的,通常。另一种方法是在事件
中保护它,而不是在拨号
中重新声明它(并且在某个地方提供了事件::ModelSimV2
的实现)。如果它真的是::ModelSimV2
,你就完全正确了。