在继承的std ::地图与基类值(Inheritance in std::map with base

2019-10-19 03:59发布

下面是一个代码:

class Base {
    public:
        long index;
};
class Derived : public Base {
    public:
        bool value;
};

void call(map<char *, Base *> *base) {
    map<char *, Base *>::iterator it = base->begin();
    cout << it->second->index << endl;
}
void test(void) {
    map<char *, Derived *> *d = new map<char *, Derived *>;

    call(d);
}

编译器警告的错误:

error C2664: 'call' : cannot convert parameter 1 from 'std::map<_Kty,_Ty> *' to 'std::map<_Kty,_Ty> *'
1>        with
1>        [
1>            _Kty=char *,
1>            _Ty=Derived *
1>        ]
1>        and
1>        [
1>            _Kty=char *,
1>            _Ty=Base *
1>        ]
1>        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

我明白为什么这个错误发生。 我不知道如何使它发挥作用。 投什么样的,以及如何使用它?

UPD

我很抱歉的不精确性,让我解释更多的细节。 我有两套由ClassA和ClassB的表示的数据。 这两个类都有一个共同的构件 - “索引”,例如。 这两套裹成地图(特别感谢罗布用于用char *一个显著校正):

std::map<char, ClassA>
std::map<char, ClassB>

有时我需要遍历地图都得到一个共同的成员“索引”的值。 我试图避免重复代码,使只有一个功能,这两个地图迭代。

我以为我可以提取超类具有共同的成员,使功能与像这样的参数:

std::map<char, SuperClassAB>

要么

std::map<char, SuperClassAB>::iterator

不过貌似这是一个坏主意。

UPD2

一个聪明的家伙给我的解决方案:

template <class T>
void call(map<char, T> *base) {
    map<char, T>::iterator it = base->begin();
    cout << it->second->index << endl;
}
void test(void) {
    map<char, Derived *> d;
    call(&d);
}

Answer 1:

似乎没有人还没有提出这一点,但你也可以让call一个函数模板。

    template <class Type>
    void call(const std::map<char*,Type*> & base)
    {
        static_assert(std::is_base_of<Base, Type>::value,
                      "Function is only callable with maps "
                      "whose mapped_type is derived from Base");
        /* More stuff */
    }

这样的功能是可调用与BaseDerived和其他任何派生自Base



Answer 2:

你可以不投这些类型。 map<char*,Base*>map<char*,Derived*>如作为不同stringfloat

做最简单的事情是内部test()简单地填充map<char*,Base*>并呼吁call这一点。 提供virtual的方法Base (可能纯virtual ),并在执行这些功能的Derived

你可以尝试transform一个map<char*,Derived*>map<char*,Base*>但为了做到这一点你就算符需要:

  1. 当然知道Base*实际指向一个Derived的对象,并使用static_cast
  2. 制作Base多态性(通常通过实现virtual析构函数),并使用dynamic_cast


Answer 3:

如果你的目标是要以某种方式在派生类中“经营”,建立在基类中的虚方法和重写它来得到你想要的特定行为:

class Base
{
public:
   long index;
   virtual void doSomething()
   {
      // Do something with index
      cout << index << endl;
   }
};

class Derived : public Base
{
public:
   bool value;

   virtual void doSomething()
   {
      // Do something with value
      cout << value << endl;
   }
};

// NOTE:  I removed the pointer and made it a ref.
// NOTE:  I made it "const" because you probably don't want to alter the
// map.  If you do...
void call(const map<char *, Base *>& base)
{
   map<char *, Base *>::const_iterator it = base.begin();
   //   cout << it->second->index << endl;
   it->second->doSomething();
}

void test(void)
{
   map<char *, Base *> d;
   // Push some members into d...I didn't, but you should
   // if you want call(...) to be meaningful.
   call(d);
}

这个有帮助吗?



Answer 4:

你可能需要你的容器来存储基类指针而不是派生类的指针。

例如map<char *, Base *> *d;

此后,你应该填入你想要的任何派生类型的元素的地图。 例如

char keyA = 'A';
char keyB = 'B';
(*d)[&keyA] = new Derived();
(*d)[&keyB] = new AnotherDerived();

请问在您的实例的工作?

顺便说一句,你为什么要使用char *为重点,似乎是一个奇怪的选择。



文章来源: Inheritance in std::map with base class as value