Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/157.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;派生类是抽象错误_C++_Inheritance_Virtual_Abstract Class - Fatal编程技术网

C++ C++;派生类是抽象错误

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;

我在Dialin中遇到了一个问题,派生类是抽象的。我不知道为什么,因为我拥有的唯一虚拟函数具有相同的参数和相同的返回类型。据我所知,这是唯一的限制,但显然我错了

这是我的密码:

标题:

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++11
override
属性非常有用的地方——编译器会直接告诉您(即,在错误消息中),正如它所定义的,
Dialin::process
不会覆盖任何内容。因此,解决方案是将
ModemSimV2
的正向decl移到相应类之外。@Robᵩ: 是的,通常。另一种方法是在
事件
中保护它,而不是在
拨号
中重新声明它(并且在某个地方提供了
事件::ModelSimV2
的实现)。如果它真的是
::ModelSimV2
,那么您就完全正确了。+1。是的,它们是两个不同的类,这意味着,
Dialin
并没有真正定义基类的纯虚函数,而是添加了一个新的虚函数。@Nawaz,是的。这就是我要表达的意思。这是一个新的C++11
override
属性非常有用的地方——编译器会直接告诉您(即,在错误消息中),正如它所定义的,
Dialin::process
不会覆盖任何内容。因此,解决方案是将
ModemSimV2
的正向decl移到相应类之外。@Robᵩ: 是的,通常。另一种方法是在
事件
中保护它,而不是在
拨号
中重新声明它(并且在某个地方提供了
事件::ModelSimV2
的实现)。如果它真的是
::ModelSimV2
,你就完全正确了。