在map(c ++,STL)方面需要帮助

时间:2010-05-13 21:31:23

标签: c++ stl map polymorphism

其实我是C ++的新手。我尝试了一些东西(实际上是地图容器),但是它没有按我假设的方式工作......在发布我的代码之前,我会很快解释它。

我创建了3个类:

ClassA的   ClassDerivedA   ClassAnotherDerivedA

最后两个来自“ClassA”。

此外,我创建了一张地图:

  map<string,ClassA> test_map;

我将一些对象(来自Type ClassDerivedA和ClassAnotherDerivedA)放入地图中。请记住:映射值来自“ClassA”类型。这只会因多态性而起作用。最后,我创建了一个迭代器,它在我的地图上运行,并将用户输入与地图中的键进行比较。如果它们匹配,它将调用一个名为“printOutput”的特定方法。

还有问题: 虽然我将“printOutput”声明为“虚拟”,但是所谓的唯一方法是来自我的基类,但为什么呢? 这是代码:

#include <iostream>
#include <map>

using namespace std;

class ClassA
{
    public:
        virtual void printOutput() { cout << "ClassA" << endl;      }
};

class ClassDerivedA : public ClassA
{
    public:
        void printOutput() { cout << "ClassDerivedA" << endl;       }
};

class ClassAnotherDerivedA: public ClassA
{
    public:
        void printOutput() { cout << "ClassAnotherDerivedA" << endl;        }
};

int main()
{
    ClassDerivedA class_derived_a;
    ClassAnotherDerivedA class_another_a;


  map<string,ClassA> test_map;
    test_map.insert(pair<string,ClassA>("deriveda", class_derived_a));
    test_map.insert(pair<string,ClassA>("anothera", class_another_a));

    string s;

    while( cin >> s )
    {
    if( s != "quit" )
    {
        map<string,ClassA>::iterator it = test_map.find(s);
      if(it != test_map.end())
        it->second.printOutput();
    }
    else
      break;
    }

}

3 个答案:

答案 0 :(得分:13)

问题在于切片。您正在地图中存储ClassA个值。将派生类实例存储到地图中时,会将切片切换为ClassA个对象。您需要在地图中存储指针而不是值。

有关切片的更多信息,请参阅此处:What is object slicing?

答案 1 :(得分:4)

C ++不是Java。您不能将派生类型存储在基类型的变量中。例如:

Base b = Derived();

只会将Derived的Base部分存储在变量b中。为了获得多态行为,您需要使用指针,并动态创建派生类:

Base * b = new Derived();

C ++容器也是如此 - 你需要:

map <string, Base *> m;

所有这些都应该包含在每本C ++教材中 - 你使用的是哪一本?

答案 2 :(得分:4)

您遇到了“slicing”。要使虚函数正常工作,您需要使用指针或引用来调用它们。换句话说,您的map应包含指向ClassA的指针:

map<string, ClassA *> test_map

完成后请记住delete,或使用智能指针。

以下是有关切片的更多信息:hereherehere