开发者

Call one method of inherited classes without those virtual prototype

开发者 https://www.devze.com 2023-03-24 17:58 出处:网络
I have some base class A, and some number of inherited classes: class B : public A class C : public A class D : public A

I have some base class A, and some number of inherited classes:

class B : public A
class C : public A
class D : public A

I have function with parsing some config file, which use name in config call:

void do_smth<B>(...);
void do_smth<C>(...);
void do_smth<D>(...);

I have map<A*> objs; 开发者_如何转开发and in those functions happend:

void do_smth<T>(...)
{
  T *control = new T();
  ...
  objs[name] = T;
}

So i have map of pointers to A. In other function I got name, and i need to get value stored in B,C or D classes. Problem is that i can't add virtual function to any class which will return those value, because of A,B,C,D from library and B have function value(), C - text(), D - currentValue() etc. And i need function get_value() which will return result of value(), text(), currentValue() depending on class? What can you advise me to solve my problem?

I see 2 ways:

1) I can write function from pointer to classes B,C,D and call function like that get_value((B*)objs[name]); but i think it's not good.

2)I can create boost::bind object with function i need at the create B,C,D variable.

What way will be better, or could you advise me smth better?


So you have

A* a;

and don't know what type it is. Try dynamic_cast:

B* b = dynamic_cast<B*>(a);
if ( b ) 
    return b->value();
//C and D the same way


Inherit A to class X where you can add whatever virtual function you might need.

Then inherit X from B,C,D and use a X* for the polymorphism.


You could use type traits. Create type traits for each of your classes B,C,D to derive an "identifier" of each class (an enum value for example).Store this identifier along objs array. Later on you can switch-case this identifier to find out to which class you should cast each element in objs.

class A{};
class B : public A{};
class C : public A{};
class D : public A{};

enum ClassType {B_type, C_type, D_type, Unknown_type};

template<typename T>
struct Identifier{static const ClassType value = Unknown_type;};

template<>
struct Identifier<B>{static const ClassType value = B_type;};

template<>
struct Identifier<C>{static const ClassType value = C_type;};

template<>
struct Identifier<D>{static const ClassType value = D_type;};


template<typename T>
void do_smth()
{
  T *control = new T();
  ...
  objs[name] = control;
  ids[name] = Identifier<T>::value;
}

void test()
{
    do_smth<X>(); // X is of type B, C, D

    ...

    switch (ids[name])
    {
    case B_type:
        {
            B* b = static_cast<B*>(objs[name]);
            // do something with b
            break;
        }
    case C_type:
        {
            C* c = static_cast<C*>(objs[name]);
            // do something with c
            break;
        }
    case D_type:
        {
            D* d = static_cast<D*>(objs[name]);
            // do something with d
            break;
        }
    default:
        ;//error
    };      
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号