鉴于这些定义和一些代码用于说明目的:
class Child
{
private:
std::string name;
public:
Child(const std::string & name) name(name)
{ }
}
template<typename T>
class Parent : public Child
{
private:
T data;
public Parent(const std::string & name, const T & data) : Child(name), data(data)
{ }
inline GetData() const
{
return this->data;
}
}
std::vector<std::unique_ptr<Child>> values;
values.emplace_back(std::make_unique<Parent<int>>("value a", 4));
values.emplace_back(std::make_unique<Parent<std::string>>("value b", "test"));
for (const auto & v : values)
{
// I want to access the int and string here!
}
如何从基类中确定父类中使用的类型?
我正在使用的具体方案实际上是我有一堆SqlParameterBase
类,其中包含有关存储过程的SQL参数的信息以及应该包含在SqlParameter<T>
模板中的std::vector<std::unique_ptr<SqlParameterBase>>
模板{1}}并传递给表示存储过程配置的类,以便可以调用它。
但这里的基本问题是我需要访问底层数据,我想避免在基类中定义void *
以包含指向数据的指针。我希望它尽可能安全。
我也愿意采用其他设计或方法来解决这个问题,所以如果你觉得它更好,请随意提出完全不同的建议。
答案 0 :(得分:0)
试试这个程序(对于这个问题:我如何从基类中确定父类中使用的类型?):
输出打印类型.. 但是需要做更多的工作才能看起来更好
value a of type:i
value b of type:NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
这里“i”表示第一行中的整数。
第二个中有“basic_string”。但是它周围有些垃圾。
我发布这个是因为它可能会引发更好的想法。
为修改的代码添加了注释。
//g++ 5.4.0
#include <iostream>
#include <string>
#include <vector>
#include <memory>
//CREATED ANOTHER VARIABLE AND FUNCTION FOR TYPENAME.
//MODIFIED CONSTRUCTOR ACCORDINGLY.
class Child
{
private:
std::string name;
std::string tyName;
public:
Child(const std::string & name,const std::string &tyname):name(name), tyName (tyname)
{ }
std::string getName()
{
return name;
}
std::string getTypeName()
{
return tyName;
}
};
//MODIFIED CONSTRUCTOR TO PASS THE TYPENAME TO PARENT CLASS.
template<typename T>
class Parent : public Child
{
private:
T data;
public:
Parent(const std::string & name, const T & data) : Child(name,typeid(data).name()), data(data)
{ }
inline T GetData() const
{
return this->data;
}
};
int main()
{
std::vector<std::unique_ptr<Child>> values;
values.emplace_back(std::make_unique<Parent<int>>("value a", 4));
values.emplace_back(std::make_unique<Parent<std::string>>("value b", "test"));
//GET THE POINTER OF YOUR BASE CLASS.
//PRINT THE TYPE NAME.
for (const auto & v : values)
{
Child *p = dynamic_cast<Child*>(v.get());
std::cout<<p->getName()<<" of type:"<<p->getTypeName()<<std::endl;
}
return 0;
}
答案 1 :(得分:0)
您希望仅在派生类型中存在的子承诺功能(返回类型化数据)。在继承下,这是抽象功能。所以一组推测的虚拟访问器。这里并不需要向上倾斜。
我会说。如果你不希望Child承诺它返回什么,只是它返回某些东西然后你的界面看起来太广泛了,你就把界面放在代替消耗界面的代码中,比如说与投机演员等。
可以通过Child中定义的接口来连接一组Child,或者它们具有仅在Derived中可用的某些特殊功能,并且必须以这种方式说出。
作为一个小附录,您可能会考虑std::vector<std::variant<type1, type2, ...>>
而不是完全错误地修改容器中的类型信息? std :: variant是C ++ 17 ofc所以可能不合适,但有第三方实现 - boost变体等。