C++基类列表以及如何确定类类型

C++ List of Base Classes and How to Determine Class Type

本文关键字:何确定 类型 基类 列表 C++      更新时间:2023-10-16

我有一个基类line,它有一个子类arc(注意,其他类将从line继承)。。。我需要存储一个列表,或者line对象的vector,它可能是linearcarc具有line没有的附加属性。因此,当我使用我的列表或line对象的vector时,我如何确定该对象是line还是arc

我已经准备了一个小的示例程序,并在注释中添加了伪代码,这是我试图实现的一个示例。这可能吗?

#include <iostream>
#include <vector>
#include <iterator>
using namespace std;
struct point
{
    double x;
    double y;
};
class line
{
    public:
        point start;
        point end;
};
class arc: public line
{
    public:
        point center;
};

int main( int argc, char* argv[] )
{

    vector<line*> a;
    a.push_back( new line );
    a.push_back( new arc );
    for( vector<line*>::iterator i = a.begin(); i < a.end(); i++ )
    {
        (*i)->start.x = 10;
        (*i)->start.y = 11;
        (*i)->end.x = 101;
        (*i)->end.y = 102;
        //if( type of (*i) is arc ) 
        //{
        //  (i)->center.x = 111;
        //  (i)->center.y = 112;
        // }
    }
    return 0;
}

在循环中,尝试以下操作:

arc *ar = dynamic_cast<arc *>(*i);
if ( NULL != ar ) {
 // it's an arc!
}else {
  // it's just a line
}

希德也是对的。。。请使用虚拟函数。在这种简单的情况下使用dynamic_cast通常被认为是一种糟糕的风格。

class curve
{
public:
    typedef void * type;
public:
    virtual type rtti() const = 0;
};
#define     
DEFINE_RTTI  
    public: 
        virtual type rtti() const { return desc(); }        
    public: 
        inline static type desc() { return &desc; } 
class line : public curve
{
    DEFINE_RTTI;
};
class arc : public curve
{
    DEFINE_RTTI;
};
///////////////////////////////////////////////////////////////////////////////
//  Main program
int main()
{
    arc arc_;
    line line_;
    curve *curve_ = new arc();
    _ASSERT(arc_.rtti() == arc::desc());
    _ASSERT(arc_.rtti() != line::desc());
    _ASSERT(line_.rtti() != arc::desc());
    _ASSERT(line_.rtti() == line::desc());
    return 0;
}

这个rtti在一个模块(exe或dll)中工作,如果你想在几个模块中使用它,你必须构建类字典

为什么需要确定?如果您绝对需要,您可以通过RTTI使用typeid字段。但通常情况下,如果你使用虚拟方法,如果你的程序设计得很好,你就不需要知道类是什么。在基类引用或指针上调用虚拟函数会根据它所指向的内容调用相应实例的方法。这就是通过类层次结构实现多态性的全部意义。

但是,如果您绝对需要知道实例属于哪个类,请使用typeid

此外,您不能通过基类指针访问派生类成员数据。您只能通过基类接口进行对话。这就是抽象的全部意义。一种丑陋的方法是创建一个胖接口,将基类接口中的这些数据成员的访问器/赋值器作为虚拟成员函数。