下面是一个代码:
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);
}
似乎没有人还没有提出这一点,但你也可以让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 */
}
这样的功能是可调用与Base
, Derived
和其他任何派生自Base
。
你可以不投这些类型。 map<char*,Base*>
和map<char*,Derived*>
如作为不同string
和float
。
做最简单的事情是内部test()
简单地填充map<char*,Base*>
并呼吁call
这一点。 提供virtual
的方法Base
(可能纯virtual
),并在执行这些功能的Derived
。
你可以尝试transform
一个map<char*,Derived*>
从map<char*,Base*>
但为了做到这一点你就算符需要:
- 当然知道 ,
Base*
实际指向一个Derived
的对象,并使用static_cast
。 - 制作
Base
多态性(通常通过实现virtual
析构函数),并使用dynamic_cast
如果你的目标是要以某种方式在派生类中“经营”,建立在基类中的虚方法和重写它来得到你想要的特定行为:
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);
}
这个有帮助吗?
你可能需要你的容器来存储基类指针而不是派生类的指针。
例如map<char *, Base *> *d;
。
此后,你应该填入你想要的任何派生类型的元素的地图。 例如
char keyA = 'A';
char keyB = 'B';
(*d)[&keyA] = new Derived();
(*d)[&keyB] = new AnotherDerived();
请问在您的实例的工作?
顺便说一句,你为什么要使用char *
为重点,似乎是一个奇怪的选择。