代码之家  ›  专栏  ›  技术社区  ›  djeidot

什么时候我应该使用C++中的Type?

  •  63
  • djeidot  · 技术社区  · 16 年前

    在我多年的C++(MFC)编程中我从来没有觉得需要使用 typedef 所以我不知道它是用来干什么的。我应该在哪里使用它?有没有真正的情况下使用 类型定义 优先考虑?或者这是一个更具体的C关键字?

    12 回复  |  直到 6 年前
        1
  •  81
  •   j_random_hacker    8 年前

    模板元编程

    typedef 必要的 对于许多 template metaprogramming 任务——每当一个类被视为“编译时类型函数”时, 类型定义 用作“编译时类型值”以获取结果类型。例如,考虑将指针类型转换为其基类型的简单元函数:

    template<typename T>
    struct strip_pointer_from;
    
    template<typename T>
    struct strip_pointer_from<T*> {   // Partial specialisation for pointer types
        typedef T type;
    };
    

    示例:类型表达式 strip_pointer_from<double*>::type 评估为 double . 注意,模板元编程在库开发之外并不常用。

    简化函数指针类型

    类型定义 有益的 为复杂的函数指针类型提供简短、尖锐的别名:

    typedef int (*my_callback_function_type)(int, double, std::string);
    
    void RegisterCallback(my_callback_function_type fn) {
        ...
    }
    
        2
  •  31
  •   Indeed is Trash    16 年前

    在比亚恩的书中,他指出可以使用typedef来处理具有不同整数大小的系统之间的可移植性问题。(这是释义)

    在sizeof(int)为4的机器上

    typedef int int32;
    

    然后在代码中的任何地方使用int32。当你移动到C++的一个实现时,siZeof(int)是2,那么你可以只改变类型

    typedef long int32;
    

    您的程序仍将在新的实现上工作。

        3
  •  18
  •   yesraaj    16 年前

    与函数指针一起使用

    隐藏typedef的函数指针声明

    void (*p[10]) (void (*)() );
    

    只有很少的程序员知道P是一个“指向返回void的函数的10个指针数组,以及指向返回void且不带参数的另一个函数的指针数组”,这种繁琐的语法几乎无法识别。但是,您可以通过使用typedef声明来大大简化它。首先,为“指向返回void且不带参数的函数的指针”声明typedef,如下所示:

      typedef void (*pfv)();
    

    接下来,根据前面声明的typedef为“指向返回void并获取pfv的函数的指针”声明另一个typedef:

     typedef void (*pf_taking_pfv) (pfv);
    

    既然我们已经创建了一个pf_,将pfv typedef作为笨拙的“指向返回void和接受pfv的函数的指针”的同义词,那么声明一个由10个这样的指针组成的数组就轻而易举了:

      pf_taking_pfv p[10];
    

    from

        4
  •  17
  •   Eva    12 年前

    只是举几个例子说明一下:STL容器。

     typedef std::map<int,Froboz> tFrobozMap;
     tFrobozMap frobozzes; 
     ...
     for(tFrobozMap::iterator it=frobozzes.begin(); it!=map.end(); ++it)
     {
         ...
     }
    

    甚至使用typedef,比如

    typedef tFrobozMap::iterator tFrobozMapIter;
    typedef tFrobozMap::const_iterator tFrobozMapCIter;
    

    另一个例子:使用共享指针:

    class Froboz;
    typedef boost::shared_ptr<Froboz> FrobozPtr;
    

    [更新] 根据评论-放在哪里?

    最后一个示例-使用 shared_ptr -很容易:是真正的收割台材料-或至少是一个前进的收割台。无论如何,您确实需要共享资源指针的前向声明,它声明的一个优点是,与前向decl一起使用是安全的。

    换一种说法:如果有共享的指针,您可能应该只通过共享指针使用该类型,因此分离声明没有多大意义。

    (是的,XYZFWD.H是一种疼痛。我只在热点使用它们-知道热点很难识别。归咎于C++编译+链接模型…

    我通常在声明容器变量的地方使用容器typedef—例如,当实际容器实例是类成员时,本地用于局部变量,作为类成员。如果实际的容器类型是一个实现细节,这将很好地工作-不会导致额外的依赖。

    如果它们成为 特定的 接口,它们与使用它们的接口一起声明,例如

    // FrobozMangler.h
    #include "Froboz.h"
    typedef std::map<int, Froboz> tFrobozMap;
    void Mangle(tFrobozMap const & frobozzes); 
    

    当类型是不同接口之间的绑定元素时(即多个头需要相同的类型),就会出现问题。一些解决方案:

    • 将其与包含的类型一起声明 (适用于经常用于此类型的容器)
    • 将它们移到单独的标题
    • 移动到单独的头,并使其成为一个数据类,其中实际容器又是一个实现细节。

    我同意后两个不是很好,我只有在遇到麻烦时才使用它们(不是主动的)。

        5
  •  5
  •   Emiliano    16 年前

    typedef在很多情况下都很有用。

    基本上,它允许您为一个类型创建一个别名。当/如果您必须更改类型时,代码的其余部分可以保持不变(这当然取决于代码)。 例如,假设你想要一个C++的ITER向量

    vector<int> v;
    
    ...
    
    for(vector<int>::const_iterator i = v->begin(); i != v.end(); i++) {
    
    // Stuff here
    
    }
    

    将来你可能会考虑用一个列表来改变向量,因为你必须对它进行操作。如果没有typedef,则必须更改代码中所有出现的向量。 但如果你写这样的话:

    typedef vector<int> my_vect;
    
    my_vect v;
    
    ...
    
    for(my_vect::const_iterator i = v->begin(); i != v.end(); i++) {
    
    // Stuff here
    
    }
    

    现在您只需更改一行代码(即从 typedef vector<int> my_vect “to” typedef list<int> my_vect “)一切正常。

    typedef还可以节省您在具有复杂数据结构时的时间,这些数据结构非常长(而且难以读取)。

        6
  •  5
  •   dsimcha    16 年前

    使用typedef的一个很好的理由是,如果某个对象的类型可能发生更改。例如,假设现在16位整数可以为某些数据集建立索引,因为在可预见的将来,您将拥有少于65535个项,并且空间约束非常重要,或者需要良好的缓存性能。但是,如果您需要在超过65535个项目的数据集上使用程序,那么您希望能够轻松地切换到更宽的整数。使用typedef,您只需要在一个地方更改它。

        7
  •  4
  •   Ztyx    12 年前

    typedef 允许不仅具有复杂类型的别名,而且为您提供了记录类型的自然位置。我有时会将它用于文档目的。

    有时我也会使用字节数组。现在,字节数组可能意味着很多事情。 类型定义 方便地将字节数组定义为“hash32”或“filecontent”,以提高代码的可读性。

        8
  •  2
  •   xtofl Adam Rosenfield    16 年前

    typedef的实际用途:

    • 为长循环模板类型提供友好的别名
    • 为函数指针类型提供友好的别名
    • 为类型提供本地标签,例如:

      template<class _T> class A
      {
          typedef _T T;
      };
      
      template<class _T> class B
      {
          void doStuff( _T::T _value );
      };
      
        9
  •  2
  •   Imran Al Noor    9 年前

    当我们想要启用一种 独立于容器的代码 (但不完全是!)

    假设你有课:

    Class CustomerList{
    
    public:
        //some function
    private:
        typedef list<Customer> CustomerContainer;
        typedef CustomerContainer::iterator Cciterator;
    };
    

    上面的代码使用typedef封装了内部容器实现,即使将来列表容器需要更改为vector或deque,customerList类的用户仍然不需要担心确切的容器实现。

    因此,typedef封装并在一定程度上帮助我们编写与容器无关的代码。

        10
  •  0
  •   Leonidas    16 年前

    每当它使源代码更清晰或更好地阅读时。

    对于泛型/模板,我使用C中的typedef类型。“nodemapping”只是更好地阅读/使用和理解,而不是很多“dictionary<string,xmlnode>”。恕我直言。所以我推荐它作为模板。

        11
  •  0
  •   zx485 potemkin    8 年前

    typedef允许类中的灵活性。当您想要更改程序中的数据类型时,您不需要更改多个位置,只需要更改一个事件。

    typedef <datatype example  int or double> value_type
    

    你可以给任何名字而不是 value_type 但是 值类型 通常是标准名称。

    所以你可以使用typedef-like

    value_type i=0;     //same as a int or double i=0; 
    
        12
  •  -1
  •   xtofl Adam Rosenfield    16 年前

    …对于枚举或结构,不需要typedef。

    或者你呢?

    typedef enum { c1, c2 } tMyEnum;
    typedef struct { int i; double d; } tMyStruct;
    

    可以写得更好

    enum tMyEnum { c1, c2 }
    struct  tMyStruct { int i; double d; };
    

    对吗?C怎么样?