Как говорили другие комментаторы, C ++ не имеет общего базового класса для каждого объекта. Теоретически, вы можете создать свой собственный и извлечь из него все:
class Object
{
protected:
Object(){};
virtual ~Object(){};
public:
virtual std::string toString() const {return("");};
}; // eo class Object
Это, однако, не поможет вам с целочисленными типами, такими как int, short. Вы должны сделать свой собственный:
class Int : public Object
{
private:
int m_nVal;
public:
Int(int _val = 0) : m_nVal(_val){};
Int(const Int& _rhs) : m_nVal(_rhs.m_nVal){};
virtual ~Int(){};
// operators
operator int() const {return(m_nVal);}
bool operator == (const Int& _rhs) const {return(m_nVal == _rhs.m_nVal);};
bool operator == (int _val) const {return(m_nVal == _val);};
Int& operator = (const Int& _rhs) {m_nVal = _rhs.m_nVal; return(*this);}:
Int& operator = (int _val) {m_nVal = _val; return(*this);};
// .... and all the other operators
// overrides
virtual std::string toString() const
{
std::ostringstream oss;
oss << m_nVal;
return(oss.str());
};
}; // eo class Int
Тогда вам придется сделать это для всех других типов, которые вы хотите использовать. После этого вы можете передать их, как если бы они были целыми числами, bools, longs и т. Д. (Благодаря перегрузке оператора). Лучшим методом было бы использовать шаблонный класс для целочисленных типов:
template<class T> class IntegralType : public Object
{
private:
T m_Val;
public:
// rest of class looks the same
}; // eo class IntegralType<>
Затем напечатайте их:
typedef IntegralType<int> Int;
typedef IntegralType<short> Short;
typedef IntegralType<long> Long;
Даже если использовать шаблонный класс, подобный этому, чтобы избавиться от лишнего труда, вам все равно понадобится специализация для строк / bools. Реализация оператора ++ на IntegralType <> будет хорошо работать для чисел, но будет вызывать std :: string.
Если вы пошли по шаблону маршрута, у вас теперь есть «Объект», целочисленные типы и некоторые специализации для строк, bools. Но чтобы имитировать .NET еще больше, вы, вероятно, хотите ввести интерфейсы для сравнения:
template<class T> class IEquitable
{
public:
virtual Equals(T _other) = 0;
}; // eo class IEquitable<>
Это можно легко подключить к вашим классам IntegralType <> и специализациям.
Но, как заметил другой комментатор, зачем вам? boost :: any полезен, если вы пытаетесь сделать что-то вроде кортежа с именем и значением произвольного типа. Если вам нужно собрать коллекцию из них, то с вашим дизайном что-то в корне не так. Например, во всех моих программах на C # мне никогда не приходилось писать:
List<Object> list = new List<Object>();
Возможно, было:
List<Vehicle> list;
List<Employee> List;
Dictionary<string, Alien> aliens;
Но никогда ничего на уровне объектов. Зачем? Ну, кроме того, чтобы вызвать ToString () или, возможно, сделать рискованное приведение, зачем вам это нужно? Обобщения существуют в программировании, поэтому нам не нужно иметь списки объектов (или в случае C ++, void *).
Так что у вас это есть. Выше показано, как у вас могут быть объекты и целочисленные типы, вроде C #, и я пропустил множество вещей. Теперь пришло время взглянуть на ваш дизайн и решить, действительно ли это то, что вам нужно.