【问题标题】:Inheriting from Abstract Class in C++从 C++ 中的抽象类继承
【发布时间】:2017-06-13 02:21:22
【问题描述】:
#include <iostream>
#include <ostream>
using namespace std;

enum Month
{
    jan = 1,
    feb,
    mar
};

class Show
{
public:
    virtual void Display() = 0;
};

class Date : public Show
{
private:
    Month m;
    int day;
    int year;
public:
    Date( Month mName, int dayName, int yearName )
    {
        m = mName;
        day = dayName;
        year = yearName;
    }
    void Display()
    {
        cout << this->m << endl;
    }
};

void displayData( void *data[] )
{
    Month m = *( reinterpret_cast<const Month*> ( data[ 0 ] ) );
    cout << m << endl;
}

int main( int argc, char**argv )
{
    Date d1( jan, 28, 2017 );
    void * data[ 1 ];
    data[ 0 ] = &d1;
    displayData( data );
    return 0;
}

我在函数 void displayData 中得到了正确的 Month m 值,但是当我从抽象类 Show 继承 Date 类时,我得到了 Month m 的垃圾值。谁能告诉我为什么会这样?

【问题讨论】:

  • 派生类有一个指向虚函数的指针表,似乎放在类的开头。
  • 更不用说糟糕的类型转换与完全无关的东西,所以继承与此无关。你想要像stackoverflow.com/questions/670734/… 这样的东西吗?或者只使用 d1.m
  • 感谢您的回复。有没有办法解决这个问题?
  • 如果您要使用void* 强制转换将它们剥离,为什么还要定义所有这些类型呢?当然displayData 至少应该采用Show 参数?无论如何,你强迫它把 Date 解释为 Month 所以你可能只会得到垃圾。
  • 在那个数据数组中我可以有其他不同类的对象,所以我将它转换为 void *.我强制 Date 解释为 Month 以便获取 Month 值并根据月份值进一步处理。有没有其他方法可以做到这一点?

标签: c++ abstract-class


【解决方案1】:

您将Date 重新解释为Month。因此,您假设这是一个安全的转换,但事实并非如此。当Date 类只是普通数据时,它碰巧完全是偶然的,但是当你从Show 派生Date 类时,类的结构变得更加复杂,并且这种意外不再成立。

可能发生的情况是Date 中的第一个元素现在是指向类的虚方法表的指针,而不是类中声明的第一个成员。

【讨论】:

    【解决方案2】:

    您不应该使用 void 指针。改用 Show 之类的基类,例如:

    void displayData( Show *data[] )
    {
        data[0]->Display();
    }
    
    int main( int argc, char**argv )
    {
        Date d1( jan, 28, 2017 );
        Show* data[ 1 ];
        data[ 0 ] = &d1;
        displayData( data );
        return 0;
    }
    

    否则你将如何分配指向它们的类的 void 指针?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-10
      相关资源
      最近更新 更多