Что такое эквивалент C ++ общего? - PullRequest
5 голосов
/ 10 апреля 2011

предположим, что я реализую полиморфную древовидную структуру данных, которая может принимать данные любого типа ...

Tree<Int> or Tree<String> or Tree<Object>

, но я реализую ее в C ++ .... как бы я указать этодерево может содержать произвольный тип, подобный универсальным в Java

, также существует эквивалент объекта Object Java в C ++, в котором все объекты в C ++ наследуют Object

Ответы [ 7 ]

3 голосов
/ 10 апреля 2011

Если ваша цель состоит в том, чтобы иметь один контейнер, который может содержать что угодно, вы можете сделать тип значения контейнера Boost Any .Но, похоже, вы ищете однородный контейнер, и ответы на этот шаблон здесь имеют смысл.

3 голосов
/ 10 апреля 2011

Ближайшим эквивалентом универсального языка Java является шаблон в C ++. Это не эквивалентно как таковой, если строго говоря. Но это то, что вы в C ++. Поэтому, чтобы удовлетворить ваши потребности, вы должны немного поработать, чтобы написать эквивалентный код на C ++.

Вот несколько ссылок на некоторые статьи, которые сравнивают шаблон C ++ с обобщениями Java:

1 голос
/ 10 апреля 2011

Вы используете язык шаблонов: Tree<Int> или Tree<String> не должны содержать объекты любого типа;они специально содержат целые числа или строки.Только Tree<Object> сможет содержать «любой» тип, но C ++ не имеет понятия, эквивалентного «объекту».Возможно, вы сможете удерживать «любой» тип в своем дереве, используя Boost.Any , хотя я сам не использовал его.

Используйте шаблоны C ++ для хранения определенного типа:

template<typename T>
class Tree {
    ...
};

Использование:

Tree<int> treeOfInts;
1 голос
/ 10 апреля 2011

То, что вы ищете, это C ++ шаблоны .

Вы можете объявить шаблонный класс как:

template<class TType>
class AClass
{
private:
    TType *somePointer;
};

Классы не являются производными от общей базы в C ++, как они делают в таких языках, как C # и Java. Самое близкое, что вы получите, это void*, но это выбрасывает всю безопасность типов, и я бы не рекомендовал это.

1 голос
/ 10 апреля 2011

В C ++ вы используете шаблоны в форме

template <typename T>
    class Tree {
        TreeNode<T> Root
        ...
    };

Шаблоны не идентичны шаблонам, они предлагают немного больше гибкости (и больше возможностей стрелять себе в ногу).Например, нельзя ограничить параметр типа шаблона подклассом определенного типа.А в C ++ нет строгой проверки типов внутри шаблона, поэтому легко можно создать беспорядок.

0 голосов
/ 10 апреля 2011

Хорошо, наивная попытка генериков java будет Tree<void*>.Это не очень хорошо, и многие люди заменят это следующим:

class TreeBase { };
class TreeInt : public TreeBase { int i; };

А затем используйте Tree<TreeBase*>.Это позволяет вам указать, какие типы будут совместимы с ним.Это эквивалент объекта Java.

Еще один слой будет иметь Tree<Node> n; с простым struct Node { TreeBase *b; };

Но поскольку мы говорим о деревьях, в c ++ есть гораздо лучший способ сделать это, поскольку он поддерживается напрямую.с помощью классов c ++:

class TreeNode { virtual ~TreeNode() { } };
class MyIntTreeNode : public TreeNode {
public:
    MyTreeNode(int i) : i(i) { }
    int i;
};
class MyStringTreeNode : public TreeNode {
public:
   MyStringTreeNode(string s) : s(s) { }
   string s;
};
class MyArrayTreeNode : public TreeNode {
public:
   MyArrayTreeNode(std::vector<TreeNode*> v) : v(v) { }
   std::vector<TreeNode*> v;
};

Создание дерева не может быть проще, если доступны необходимые типы:

int main() {
  MyIntTreeNode n1(10);
  MyStringTreeNode n2("abc");
  std::vector<TreeNode*> v;
  v.push_back(&n1);
  v.push_back(&n2);
  MyArrayTreeNode n3(v);
  algo(n3);
  }

Этот подход имеет то преимущество, что каждый триод может иметь различное поведение.Недостатком является то, что это немного многословно.

0 голосов
/ 10 апреля 2011
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...