假设我有一个基础抽象类:
class Base
{
public:
virtual ~Base(){};
};
并从它模板类派生:
template<typename T>
class Derived : public Base
{
public:
void function();
};
另一个类Test,它具有Base类对象的向量
class Test
{
public:
vector< Base* > base_vector;
};
问题1:如果我们有一个指向Base类对象的指针向量,那么它们也可以填充指向Derived类的指针,对吗?
所以,现在让我说从现有的测试类中访问这个向量,该测试类以前填充了指向派生类类型对象的指针
void (Test test)
{
vector<Base*> objects = test.base_vector;
}
问题2:是否可以推导出衍生对象的类型名称,指针指向哪个? (派生类是模板)
OR是否可以调用Derived类中定义的function(),而不关心Derived类的类型?
如果没有,那么应该对这些类中的任何一个进行哪些最小的更改?
答案 0 :(得分:1)
如果我正确理解您的问题,那么您需要使用虚拟功能。如果要调用对象上的函数并确保调用正确类型的函数,请将 @Html.TextBox("Napisz", null, new { @class = "ostatni" })
虚拟化。所以你需要在function
课程中声明它。此外,您需要使矢量成为Base
指针的向量。然后当你在向量的对象上调用Base
时,如果对象确实是派生类型,它将从派生类调用该函数。
这样你就不需要找出对象的类型了,你只需调用虚函数,它就会找出它是什么类型的对象并调用正确的函数。
答案 1 :(得分:1)
我不确定我是否理解您的需求,但是您的代码修改是否适合您?这样您就可以根本不需要推断类型,或者您可以获得一个虚拟type()
方法,它将为您返回一个枚举,其中包含每种类型的一些唯一值。
#include <memory>
#include <string>
#include <vector>
#include <iostream>
class Base {
public:
virtual void function() = 0;
virtual ~Base() = default;
};
template <class T> class Derived : public Base {
public:
void function() override {
// to produce some output
std::cout << typeid(T).name() << std::endl;
}
};
class Test {
public:
std::vector<std::unique_ptr<Base>> objects;
};
int main() {
Test test;
test.objects.push_back(std::make_unique<Derived<int>>());
test.objects.push_back(std::make_unique<Derived<std::string>>());
for (auto &ptr : test.objects) {
ptr->function();
}
}
此问题的替代解决方案是使用variant
类,例如boost::variant或std :: experimental :: variant(如果标准库已有)。这样您就不需要在Base类中拥有virtual function()
。 boost::variant
具有返回您的which()
方法和类型列表中的整数类型。一个例子:
#include <boost/variant.hpp>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
class Base {
public:
virtual ~Base() = default;
};
template <class T> class Derived : public Base {
public:
void function() {
std::cout << typeid(T).name() << std::endl;
}
};
class Test {
public:
std::vector<boost::variant<Derived<int>, Derived<std::string>>> objects;
};
int main() {
Test test;
test.objects.push_back(Derived<int>());
test.objects.push_back(Derived<std::string>());
for (auto& obj : test.objects) {
switch (obj.which()) {
case 0:
boost::get<Derived<int>>(obj).function();
break;
case 1:
boost::get<Derived<std::string>>(obj).function();
break;
}
}
return 0;
}