问题描述:

I have a base class line which has a child class arc (note that additional classes will inherit from line)... I need to store a list, or vector of line objects that may be a line or an arc. arc has an additional property that line does not. So as I'm working with my lists, or vector of line objects, how do I determine whether the object is a line or an arc?

I have prepared a small sample program and put in comments with pseudo-code a sample of what I would be trying to accomplish. Is this even possible?

#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;

}

网友答案:

In your loop, try this:

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

Sid is also right...use virtual functions for this instead. Using dynamic_cast for simple cases such as this is generally considered poor style.

网友答案:
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;
}

This rtti works inside one module (exe or dll), if you want use it in several modules you have to build class dictionary

网友答案:

Why do you need to determine? If you absolutely need to you can use the typeid field via RTTI. But normally if you use virtual methods, if your program is well designed you shouldn't need to know what a class is. Calling a virtual function on a base class reference or pointer will call the appropriate instance's method based on what it is pointing to. That's the whole point of having polymorphism via class hierarchies.

But again, use typeid if you absolutely need to know what class an instance belongs to.

Also, you can't access derived class member data via base class pointers. you can only talk via the base class interface. that's the whole point of abstraction. One ugly way around is to create a fat interface that is give accessors/mutators to these data members in your base class interface as virtual member functions.

相关阅读:
Top