我对typedef的理解是给一个声明一个别名。 现在将这种int声明称为Integer。但为什么?为什么有人会使用typedef?什么是更有利的原因?
typedef int Integer;
Integer blamo = 50;
cout << blamo << endl;
答案 0 :(得分:19)
这不是一个好例子,因为Integer
和int
没有任何不同的含义。但想象一下,
typedef int BlamoType;
现在,将来'blamo'成为64位整数时,您只需更改此typedef,所有其他代码保持不变。
typedef的另一个原因是缩短类型名称。例如,而不是
boost::shared_ptr<std::map<std::wstring, std::vector<int> > > blamo1;
boost::shared_ptr<std::map<std::wstring, std::vector<int> > > blamo2;
std::vector<boost::shared_ptr<std::map<std::wstring, std::vector<int> > > > blamoList;
你可以这样做:
typedef boost::shared_ptr<std::map<std::wstring, std::vector<int> > > BlamoType;
BlamoType blamo1;
BlamoType blamo2;
std::vector<BlamoType> blamoList;
答案 1 :(得分:11)
这里没有提到的原因是:编写通用代码。考虑像std::vector
这样的容器的实现。它应该有一个名为std::vector<T>::value_type
的类型,因此任何编写通用代码的人都可以使用它:
template<class Container> void f(const Container &c)
{
typename Container::value_type v = c.back();
// ...
}
你怎么能在课堂上介绍这样的类型?唯一的方法是typedef:
// !!!EXPOSITION ONLY!!!
template<class T> class vector
{
public:
typedef T value_type;
// ...
};
答案 2 :(得分:7)
所以你只需输入
boost::shared_ptr<std::map<std::string,std::string>>
一次?
答案 3 :(得分:4)
另一个需要考虑的案例;函数原型/指针。你是否想在每次定义一个以函数指针作为参数的方法时写这个?
int Search( void* key, void* array, int len, int (*someFunc)(void*, void*) )
{
// do stuff, call passed in function, etc.
}
我宁愿这样做
typedef int (*ComparisonFunc)(void*, void*)
int Search( void* key, void* array, int len, ComparisonFunc fn )
{
// do stuff, call passed in function, etc.
}
在这里原谅C比较函数,这个概念也适用于C ++(但是你不会在指向void的指针上实现泛型)
答案 4 :(得分:3)
嗯,确实不要将名称更详细。
主要有三个原因。
一,使名称更简洁&amp;更容易打字。在处理类和/或模板时,这种好处经常发挥作用。例如,如果map
和某个对象之间有string
,那么使用typedef可以减少这样的结构:
for( std::map<string, MyObj>::iterator it = my_map_.begin(); it != my_map_.end(); ++it )
到此:
typedef std::map<string, MyObj> MyMap;
for( MyMap::iterator it = my_map_.begin(); it != my_map_.end(); ++it )
有用性与您需要声明某些类型MyObjMap
的频率成正比。就一次?不太有用。一千次?非常有用。它还有助于使代码更清晰&amp;自我记录,特别是在声明这些类型的许多对象时。
第二个原因也可能是一个反理由。这样做是为了尝试获得一定程度的通用性和可扩展性。这尤其适用于类成员类型。我们的想法是使您的类更通用,这样当您更改成员的类型时,您不必更改调用代码。但我提到这也可能是一个反理由,因为人们常常认为这比实际上有更多的好处。回想起。您真的多久会更改一个成员的类型,例如__int32
到__int64
?可能有几次?这真的足以建立编码模式吗?
最后一个原因实际上是第一个原因的延伸。为函数指针提供方便的名称。
答案 5 :(得分:3)
我使用typedef至少有三个原因,其中大部分/全部已经在答案中介绍过:
- 简化:
typedef int (*funcptr)(char, unsigned long);
funcptr f; // f is a ptr to a function taking char & unsigned long, returning an int
typedef std::vector<Record> Container;
Container c; // c is a vector of Records
- 封装:
typedef unsigned short int MY_COUNTER;
MY_COUNTER c;
现在,如果以后,我想让MY_COUNTER
更大,我只需更改typedef并更新所有与计数器相关的代码(重新编译后)。请注意,如果我在计数器的任何地方明确使用了unsigned short int
,我必须浏览所有文件,并且只更改计数器的unsigned short int
用途;我不能只是全局替换所有代码中的unsigned short int
因为我可能会将它用于除计数器之外的其他东西。
- 可移植性
typedef unsigned short UINT16;
现在当我去另一个平台时,我只是在一个地方(头文件)中将UINT16
映射到其他地方(例如,unsigned long
),但我的所有代码仍然有效(在重新执行之后) -汇编)。几乎像“类型防火墙” - 它可以防止平台更改在所有代码中传播到更改。任何开发人员(特别是那些总是在多个架构和平台上处理代码的嵌入式开发人员),他们不得不经历大型C或C ++代码库。将所有出现的int
更改为short int
或与此相关的任何内容。
请注意,对于任何最近的编译器,通常都可以使用 stdint.h
&amp;一种更好的方法来实现平台可移植性。但我在许多系统上工作,其中编译器较旧且 stdint.h
不存在(或必须创建)。
typedef还有很多其他好的用途,特别是当你使用模板做更多工作时,这三种情况是一些最常见,最有用和最直观/最明显的用途(至少是IMO)。
答案 6 :(得分:2)
The power of 'typedef' in C++说:
C ++允许我们自己的定义 基于其他现有数据的类型 类型。我们可以使用 关键字typedef,格式为:
typedef existing_type new_type_name;
其中existing_type是C ++ 基本或复合类型 new_type_name是新名称 我们正在定义的类型。
例如:
typedef char C;
typedef unsigned int WORD;
typedef char * pChar;
typedef char field [50];
Some more detail about typedef Specifier
答案 7 :(得分:2)
C ++有一个非常复杂的类型系统,有些类型可能非常复杂。 typedef减少了必要的代码量。 Typedef还允许用户与类型更改隔离,最后,它允许用户符合半编译时接口 - 比如定义迭代器类型。
答案 8 :(得分:0)
其他有意义的例子可能是为数据类型提供简洁的速记,例如,作为指向struct的指针实现。