当前位置:  开发笔记 > 编程语言 > 正文

我什么时候应该在C++中使用typedef?

如何解决《我什么时候应该在C++中使用typedef?》经验,为你挑选了6个好方法。

在我多年的C++(MFC)编程中,我从未觉得需要使用typedef,所以我真的不知道它用于什么.我应该在哪里使用它?有没有使用typedef首选的真实情况?或者这真的是一个特定于C的关键字?



1> j_random_hac..:

模板元编程

typedef对于许多模板元编程任务来说是必要的- 每当一个类被视为"编译时类型函数"时,a 被用作"编译时类型值"以获得结果类型.例如,考虑一个简单的元函数,用于将指针类型转换为其基类型:typedef

template
struct strip_pointer_from;

template
struct strip_pointer_from {   // Partial specialisation for pointer types
    typedef T type;
};

示例:类型表达式strip_pointer_from::type求值为double.请注意,模板元编程在库开发之外并不常用.

简化功能指针类型

typedef有帮助的用于给出一个短,锋利的别名复杂函数指针类型:

typedef int (*my_callback_function_type)(int, double, std::string);

void RegisterCallback(my_callback_function_type fn) {
    ...
}


对于C++ 11,添加"using a = b"语法令人愉快地将"typedef"关键字留给记忆,因为typedef总是令人困惑地倒退而且与#define不一致(现在我从不会意外地反转这两个因为它是因为它是与变量赋值顺序相同).

2> Jason Punyon..:

在Bjarne的书中,他声明你可以使用typedef来处理具有不同整数大小的系统之间的可移植性问题.(这是一个意译)

在sizeof(int)为4的机器上,您可以

typedef int int32;

然后在代码中的任何地方使用int32.当您转到sizeof(int)为2的C++实现时,您只需更改typdef即可

typedef long int32;

并且您的程序仍将适用于新的实现.


当然你会使用中的uint32_t吗?:)
@KeithB:我认为稀有性取决于你的发展类型.嵌入式系统开发人员和那些经常处理文件格式的人是我经常需要知道确切大小的两种情况.

3> yesraaj..:

使用函数指针

使用typedef隐藏函数指针声明

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

只有少数程序员可以告诉p是一个"指向返回void的函数的10个指针的数组,并且指向另一个返回void且不带参数的函数的指针." 繁琐的语法几乎难以辨认.但是,您可以使用typedef声明来大大简化它.首先,声明一个typedef,用于"指向返回void且不带参数的函数的指针",如下所示:

  typedef void (*pfv)();

接下来,根据我们之前声明的typedef,为"指向函数返回void并获取pfv"的另一个typedef声明:

 typedef void (*pf_taking_pfv) (pfv);

现在我们已经创建了pf_taking_pfv typedef作为笨重的"指向函数返回void并获取pfv的指针"的同义词,声明一个包含10个这样的指针的数组是一件轻而易举的事情:

  pf_taking_pfv p[10];



4> peterchen..:

只是提供一些例子说明:STL容器.

 typedef std::map 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 FrobozPtr;

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

最后一个例子 - 使用shared_ptr- 很简单:是真正的标题材料 - 或者至少是前向标题.无论如何,你确实需要shared_ptr的前向声明,并且它声明的一个优点是可以安全地使用前向decl.

换句话说:如果有一个shared_ptr你可能只应该通过shared_ptr使用该类型,所以分离声明没有多大意义.

(是的,xyzfwd.h很痛苦.我只在热点使用它们 - 知道热点很难识别.责怪C++编译+链接模型......)

容器typedef我通常在声明容器变量的地方使用 - 例如本地用于本地var,当实际容器实例是类成员时作为类成员.如果实际容器类型是实现细节,则这很有效 - 不会产生额外的依赖性.

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

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

当类型是不同接口之间的绑定元素时,这会产生问题 - 即多个头需要相同的类型.一些解决方案

与包含的类型一起声明它(适用于经常用于此类型的容器)

将它们移动到单独的标题中

移动到单独的标头,并使其成为一个数据类,其中实际容器再次是一个实现细节

我同意后两者并不是那么好,我只有在遇到麻烦时才会使用它们(不是主动).



5> Emiliano..:

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

基本上它允许您为类型创建别名.当/如果必须更改类型时,其余代码可以保持不变(当然这取决于代码).例如,假设您想要在c ++向量上进行操作

vector v;

...

for(vector::const_iterator i = v->begin(); i != v.end(); i++) {

// Stuff here

}

在将来,您可能会考虑使用列表更改向量,因为您必须对其执行操作的类型.如果没有typedef,您必须在代码中更改所有出现的向量.但如果你写这样的东西:

typedef vector my_vect;

my_vect v;

...

for(my_vect::const_iterator i = v->begin(); i != v.end(); i++) {

// Stuff here

}

现在你只需要更改一行代码(即从" typedef vector my_vect"到" typedef list my_vect"),一切正常.

当你有很复杂的数据结构写入(并且难以阅读)时,typedef也可以节省你的时间


@xtofl:typedef和接口类型都是解决此特定问题的有效方法.接口类型更通用,但它们也更重量级.此外,正确使用接口类型意味着所有调用都是虚拟的 - 迭代器推进/解除引用的代价很高.

6> dsimcha..:

使用typedef的一个很好的理由是,某些东西的类型可能会改变.例如,假设现在,16位整数可以用于索引某些数据集,因为在可预见的将来,您将拥有少于65535个项目,并且空间限制很重要或者您需要良好的缓存性能.但是,如果您需要在超过65535项的数据集上使用程序,则希望能够轻松切换到更宽的整数.使用typedef,您只需在一个地方更改它.

推荐阅读
mobiledu2402851373
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有