我有父类:
class Data
{
public:
Data ( void ) { }
Virtual int Size ( void )
{
return 100;
}
protected:
map<string, Data*> m;
};
从类Data继承的类:
class Struct : public Data
{
public:
Struct ( void ) { }
Struct & Add ( const string & name, Data x )
{
Data * tmp = new Data ( x );
m[name] = tmp;
return *this;
}
void Print ( void )
{
for ( const auto & tmp : m )
cout << tmp . first << " " << tmp . second -> Size () << endl;
}
};
class IntData : public Data
{
public:
IntData ( void ) { }
int Size ( void )
{
return 4;
}
};
class DoubleData : public Data
{
public:
DoubleData ( void ) { }
int Size ( void )
{
return 8;
}
};
主要:
int main ( void )
{
Struct a;
a . Add ( "Integer",IntData () );
a . Print ();
return 0;
}
Current output : Integer 100
Expected output : Integer 4
我想创建一个地图,它可以容纳从Data类派生的各种类型的对象。但是当我想从map中的存储对象调用方法Size(在本例中为IntData)时应该返回4它始终从父类Data返回值。我该怎么办呢?
答案 0 :(得分:4)
你的问题是:
Data * tmp = new Data ( x );
您放入地图的实际指针是Data
父类的实例。您将从您通过值传递的参数中复制构造Data
父类的新实例作为参数。
您需要将整个功能更改为:
Struct & Add ( const string & name, Data *x)
{
m[name] = x;
return *this;
}
调用者现在负责构造任何子类的新实例:
a . Add ( "Integer",new IntData);
然后,这将按预期工作。
当然,这种方法会带来内存泄漏等各种问题......因此,您最好使用std::shared_ptr
。但这将是一个不同的问题......
答案 1 :(得分:1)
我已经为您重写了代码。
#include <unordered_map>
#include <memory>
#include <iostream>
class Data {
public:
virtual ~Data(){}
virtual int Size() = 0;
};
class Struct : public Data {
std::unordered_map<std::string, std::unique_ptr<Data>> m;
public:
Struct& Add(const std::string& name, std::unique_ptr<Data> x) {
m[name] = std::move(x);
return *this;
}
void Print() {
for(const auto& tmp : m )
std::cout << tmp.first << " " << tmp.second->Size() << "\n";
}
int Size() override {
int sum = 0;
for (const auto& tmp : m)
sum += tmp.second->Size();
return sum;
}
};
class IntData : public Data {
public:
int Size( ) override { return 4; }
};
class DoubleData : public Data {
public:
DoubleData( ) { }
int Size( ) override { return 8; }
};
int main() {
Struct a;
a.Add("Integer", std::make_unique<IntData>() );
a.Print();
}