【问题标题】:using generic class members in a class在类中使用泛型类成员
【发布时间】:2012-08-07 16:42:27
【问题描述】:

基于我的问题:C++ cannot establish handle reference to 'parent' object -- circular includes or undefined type errors 我想创建一个类(称为 Node),它有两个泛型类型成员、一个指向要确定类型的父对象的泛型指针和一个泛型向量指向一组要确定类型的子对象的元素的指针。存在于双向树结构中的对象将从 Node 继承,并且可以在数据可用时在必要时填充其父成员和子成员。这是迄今为止我对 Node.h 所做的:

#include <vector>

#ifndef NODE_H_
#define NODE_H_

template<typename T> class parent{};
template<typename T2> class child{};
class Node{

private:
parent<T>* parent_ptr;
vector<child<T2>>* children_ptr;

public:
 //some accessor methods will go here to get and set the parent and children
};
#endif /*NODE_H_*/

显然这不是在 C++ 中使用模板的正确方法,因为我收到错误 C2065“'T' is an undeclared identifier”和 C4430“缺少类型说明符 - 假定为 int”错误。我在这里找到了一些关于创建模板类和函数的有用文档:http://www.cprogramming.com/tutorial/templates.html 但该教程和我能找到的任何其他文档似乎都没有涵盖使用模板在非模板类中声明通用类成员;我相当确定这(或类似的东西)是我需要为我的用例做的,那么在标准 C++ 类中声明和使用泛型成员变量的正确方法是什么?

【问题讨论】:

  • 您似乎对 C++ 不太确定。我建议在处理模板之前先很好地掌握基本语言。在这里,您可能应该先为某些特定类型编写此代码,然后再使其成为通用类型。

标签: c++ templates generics polymorphism


【解决方案1】:

您绝对应该花一些时间了解模板的工作原理,并从简单的东西开始。我花了数年时间才能够创建复杂的模板对象而无需进行大量编译器错误调试,甚至花费了更长的时间来设计代码结构以最大限度地降低这种复杂性。

但这就是我认为你的意图。您的模板中包含太多信息,只需要将类型名称删除为 Parent 和 Child(或 T 和 T2,如果您愿意,尽管这些名称令人困惑)。

#include <vector>

#ifndef NODE_H_
#define NODE_H_

template<typename Parent, typename Child>
class Node{

private:
Parent* parent_ptr;
std::vector<Child*> children_ptr;

public:
 //some accessor methods will go here to get and set the parent and children
};
#endif /*NODE_H_*/

另外作为旁注,您可能需要父母所有权的情况,父母拥有他们的孩子并在他们完成后释放他们的记忆(如果每个孩子恰好由一位父母拥有)。在这种情况下,向量将变为:

vector<Child> children;

否则,您需要为如何删除树创建一个很好的结构。另一种方法是使用智能指针,一旦它们未使用就会自行删除(适用于难以跟踪的抽象结构)。请参阅 Boost Smart Pointers 或 C++ 更高版本中的等效项,但需要特别注意循环引用。

【讨论】:

  • 酷,谢谢。对于 Google 员工:另外值得注意的是,我省略了向量的 std 命名空间;如果没有 'using namespace std' 或指定 'std::vector',上面的代码将无法编译。请参阅下面的@pmr 答案以正确使用
  • @CCJ 很高兴它有帮助。为了正确起见,我将 std::vector 添加到答案中。
【解决方案2】:

除了添加之外,我看不到您需要 parentnode 您已经包含的数据的附加信息。这是一个 链表中的典型情况,您需要注入 nextprev 维护结构的指针。

当您已经在处理指针时,这似乎没有必要:

template<typename Parent, typename Child>
class Node {
  Parent* parent;
  std::vector<Child*> children;
};

对我来说,这仍然是一大堆指针,而且没有对象 还没有管理。

【讨论】:

    【解决方案3】:

    你的代码应该这样写:

    template<typename Parent, typename Child>
    class Node
    {
    private:
        Parent* parent_ptr;
        vector<Child>* children_ptr;
    
    public:
        //some accessor methods will go here to get and set the parent and children
    };
    

    按照您的方式,只有(空)parent 类有 T 模板参数,只有(空)child 类有T2 模板参数。

    另外,我不认为你真的想要一个指向 vector 的指针。你有可能这样做,但这是一个非常奇怪的用法。

    但实际上,我认为简单地使用继承会更有意义:

    class Node
    {
    private:
        Node* parent_ptr; // a pointer to a Node, or any Node-derived object
        vector<Node*>* children_ptr; // a vector of pointers to Nodes or Node-derived objects
    
    public:
        //some accessor methods will go here to get and set the parent and children
    };
    

    不过,vector 的指针很烦人。我可能会将我的vector 包装在一个内部处理内存分配的类中,或者查找一些 C++11 STL 智能指针类。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-21
      • 1970-01-01
      • 2014-04-13
      • 2021-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多