如果我不使用typedef,尽可能使用基元名称和强制转换
Should I avoid typedef, try to use primitive names and cast when possible?
我不确定这里的词汇,但希望我能让自己理解。
当我用不太扎实的C++知识来研究winapi时,我发现很多typedef的东西,对我来说,似乎过于复杂了这个问题,并增加了一件我必须记住的事情。
例如,UINT
而不是unsigned int
,HBITMAP
原来只是HANDLE
,还有很多其他的。
我的问题是,我是否可以/应该在可能的情况下替换该类型的更通用的版本,并在需要时将其强制转换(这叫什么)?
例如,我想写
-
void SomeFunction(unsigned int some_int) { ... }
而非void SomeFunction(UINT some_int) { ... }
-
HANDLE hBMP = LoadImage(...); ImageList_Add(... (HBITMAP) hBMP ...);
代替HBITMAP hBMP = ...
这对新人来说是好的,还是一般的坏做法,还是什么?
1)Win32 API实际上是C,而不是C++。
如果你考虑像MFC或ATL这样的东西,这两种东西都是"面向对象"的,只有C++的API,那么区别就变得更加重要了。幸运的是,这两者都已经过时了。
2) 微软喜欢使用大量的宏和typedef。我不能说这是"好"还是"坏"。这只是生活中的一个事实。如果你在Windows上工作很长时间,它将成为你的第二天性。
3) 最重要的是——是的:当你使用微软API时,你绝对应该遵守微软的约定。当MSDN页面显示"HANDLE"时使用"HANDLE"是一件好事。类似的建议适用于"LPxxx"、"TRUE"、"FALSE"、"INVALID_HANDLE"、"HRESULT"等。如果MSDN中是这样说的,那么你应该使用它。
它不仅会让你的代码更可读。。。但是,令人惊讶的是,它还可以防止"猜测"真实类型"可能导致的细微错误。
不要试图"猜测"类型。这只是个坏主意。
遵循标准惯例将使生活更轻松、更安全、更可靠、更便携。
IMHO。。。
请不要使用明显的typedef
(即UINT
代替unsigned int
)。相反,typedef
传达意义。UINT
并不比unsigned int
好(有些人可能会说它更短,但说真的,它并不是短得多的)。
在我看来,长名称的typedef
(就像std::map<unsigned int, flost>::const_iterator
的typedef
)是可以的,因为它提高了可读性。UINT
。。。没有那么多。
为特定类型/用途(如HANDLE
)传达特定含义的typedef
是不错的。在我看来,HANDLE
比使用原始void*
更好,因为a)我不在乎HANDLE
是否是void*
,b)它传达了它的目的。
用于可移植性的typedef
很好(就像32位带符号整数的typedef一样),因为它允许在平台/编译器之间进行更容易的转换。
这对新手来说是好的,对一般来说是坏的做法,还是什么
这是一种糟糕的做法。您不应该使用实际类型。
typedef通常用于在不同平台上的可移植性&编译器实现。因此,您应该避免使用实际类型,而不是typedef的名称。使用实际类型将使您的代码与平台更加紧密地耦合&您使用的编译器实现,事实上,如果组合发生变化,它可能无法正常工作。
此外,typedefed名称比实际类型更直观,也更为程序员所知,这也是您应该坚持使用这些名称的另一个原因。
Typedefs
不仅对可移植性很有用,而且对未来的验证也很有用。如果MicroSoft在某个时刻决定UINT
应该是unsigned long int
的typedef
,而不是unsigned int
,那么使用UINT
将确保您的代码继续工作。这种类型的更改是极不可能的,尤其是对于像MS这样的大公司的代码,但这个想法仍然适用:typedefs
适合许多类型的抽象。它们一点也不坏,但你偶尔会发现使用不当的例子。如果您正在使用其他人的API,请始终使用他们的typedefs
。他们可能有充分的理由进行抽象。
使用typedef有几个原因。
- 缩写某种类型:
typedef unsigned int UINT
- 可移植性:
typedef int INT64
- 可读性:
typedef HANDLE HBITMAP
我宁愿读HBITMAP hBitmap = ...
,也不愿读HANDLE hBitmap = ...
,原因与我(通常)不写Animal dog = new Dog()
相同,因为更具体可以帮助代码的读者,而且在这里你不会失去任何东西,因为根据Liskov替换原则,你可以在任何可以使用Animal
实例的地方使用dog
实例。
如果您使用C++和Boost,您也可以考虑使用BOOST_STRONG_TYPEDEF
,这基本上创建了一个简单的类,从而为您提供了一个真正的新类型(这意味着您不能像使用HANDLE
和HBITMAP
那样混合使用。
您所描述的强制转换并不是真正的强制转换,因为类型是相同的,typedef
只创建一个别名,而不是一个新类型。所以,写
HANDLE hOtherBitmap = /* some code */;
HBITMAP hBitmap = (HBITMAP) hOtherBitmap;
就像写
int i = /* some value */;
int k = (int) i;
- 防止主数据类型C++的隐式转换
- 模板参数替换失败,并且未完成隐式转换
- 努力将整数转换为链表。不知道我在这里做错了什么
- HEX值到wchar_t字符(UTF-8)的转换
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将 Qvector<uint8_t> 转换为 QString
- 如何在cuSparse中使用cusparseXcoo2csr从coo转换为csc
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 在c++中使用nlohmann从类到json的转换
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 如何使用OpenCV将RBG图像转换为HSV,并将H、S和V值保存为C++中的3个独立图像
- 复制列表初始化的隐式转换的等级是多少
- 正在将指针转换为范围
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- 'std::wstring_convert'尽可能多地转换(从 UTF8 文件读取块)
- 这个给定的代码应该将给定的数字转换为尽可能滞后的数字,no.by 用 9.It 替换合适的数字是行不通的
- 如果我不使用typedef,尽可能使用基元名称和强制转换
- 转换尽可能快的整数n之间的两个基-内置函数