6

我正在设计一个简单的Array类,它能够保存任何类型的对象,比如可以在一个对象中保存多种类型数据的向量。(这是出于学习目的。)

我有一个名为的空基类Container

class Container {};

和一个名为的模板化子类Object

template <class T>
class Object : public Container {
    T& object;
public:
    Object(T& obj = nullptr) : object(obj) {}
};

我有一个Array类,它包含一个vector指向Containers 的指针,我用它来保存Objects:

class Array {
    std::vector<Container *> vec;
public:
    template <class T>
    void add_element(const T&);
    auto get_element(int);
};

add_element将元素存储到Objects 中并将它们放入vec

template <class T>
void Array::add_element(const T& element)
{
    vec.push_back(new Object<T>(element));
}

get_element从中删除元素Object并将其传递回调用者。这就是我的问题所在。为了从 中删除元素Object,我需要知道Object它是什么类型:

auto Array::get_element(int i)
{
    return (Object</* ??? */> *)vec[i])->object;
}

有什么方法可以让我找出我存储的对象类型吗?

编辑:既然人们声称这是不可能的,那么这个怎么样。是否有某种方法可以在类中实际存储类型信息?(我知道你可以在 ruby​​ 中做到这一点)。如果我能做到这一点,我可以将返回类型存储get_element在 each 中Object

4

3 回答 3

2

我正在为您的get_element.

template <class T>
T& Array::get_element(int i, T &t)
{
    Object<T> *o = dynamic_cast<Object<T> *>(vec[i]);
    if (o == 0) throw std::invalid_argument;
    return t = o->object;
}

Array arr;
double f;
int c;

arr.get_element(0, f);
arr.get_element(1, c);

但或者,你可以使用这个:

template <class T>
T& Array::get_element(int i)
{
    Object<T> *o = dynamic_cast<Object<T> *>(vec[i]);
    if (o == 0) throw std::invalid_argument;
    return o->object;
}

f = arr.get_element<double>(0);
c = arr.get_element<int>(1);
于 2012-07-06T22:52:25.673 回答
1

函数 like 的返回类型Array::get_element必须在编译时确定。由于类Array在编译时不知道它存储什么类型的容器,唯一的选择是只返回基Container*指针。然后该代码的用户可以使用虚函数和/或dynamic_cast处理那些通用容器。

于 2012-07-06T22:19:10.347 回答
1

dynamic_cast<>(),当用于指针时,可用于检查强制转换是否实际可行,因为当类型不匹配时它返回 NULL。

但是,您可能需要重新考虑您的设置;如果可以避免动态转换,您不会想要使用它,并且具有级联“如果 object-is-type1 则执行此操作;否则如果 object-is-type2 则执行此操作;否则如果 object-is-type3 ......”几乎总是一个糟糕设计的明确标志。

在你的 get_element 中使用 auto 可能是你解决你不知道类型是什么问题的诀窍——不过,这不起作用。编译器仍然必须知道返回类型;它不能在运行时改变。

编辑:您也可以退后一步,问自己是否真的需要一个可以存储“任何东西”的数组。我已经使用 Objective-C 很长时间了,它基本上是围绕着这样一个想法构建的:一切都只是一个“对象”,人们可以在任何东西上调用任何东西,这一切都是在运行时整理出来的。但是,我发现它的实际用途很少见……特别是对于容器,我发现我使用的每个 NSArray 都只有一种类型的对象,或者可能是公共基类的对象,但实际上并不是不同的、不相关的类.

于 2012-07-06T22:20:01.673 回答