我在一些C ++代码中经常看到类似下面的代码:
typedef class SomeClass SomeClass;
我对这实际上取得的成就感到困惑。看起来这不会改变任何事情。 typedef
这样做有什么用?如果这样做有用,是否值得付出额外的努力呢?
答案 0 :(得分:20)
它会阻止这样的代码编译:
class SomeClass { ... };
int SomeClass;
这是完全合法的C ++,虽然它是可怕的。如果这样做,那么对裸SomeClass
的任何引用都会引用该变量。要引用该类,您需要在每次使用时明确说出class SomeClass
。如果您创建typedef
:
class SomeClass { ... };
typedef class SomeClass SomeClass;
int SomeClass;
然后编译器将int SomeClass
的定义标记为错误,因为它应该是正确的。
答案 1 :(得分:7)
请参阅此相关问题的上一个答案。丹萨克斯的一篇文章引用了很长的一句话,就像我遇到的任何内容一样清楚地解释了这个问题:
Difference between 'struct' and 'typedef struct' in C++?
该技术可以防止实际问题(虽然这是罕见的问题)。
这是一个廉价的保险 - 它在运行时或代码空间是零成本(唯一的成本是源文件中的几个字节),但你得到的保护是如此之小,以至于看到有人一直使用它是不常见的。我有一个包含typedef的“新类”代码段,但是如果我实际上从头开始编写一个类而不使用代码片段,那么我几乎从不打扰(或者它是否记得?)来添加typedef。
所以我说我不同意这里给出的大多数意见 - 值得把这些类型的参数放进去,但还不够,我会给任何人(包括我自己)不要把它们放进去的悲痛。
我被问到一个例子,说明没有类名称typedef'可能导致意外行为 - 这里的例子或多或少地从Saks文章中解除了:
#include <iostream>
#include <string>
using namespace std;
#if 0 // change to #if 1 to get different behavior
// imagine that this is buried in some header
// and even worse - it gets added to a header
// during maintenance...
string foo()
{
return "function foo... \n";
}
#endif
class foo
{
public:
operator string() {
return "class foo...\n";
}
};
int main()
{
string s = foo();
printf( "%s\n", s.c_str());
return 0;
}
当函数声明可见时,程序的行为会自动更改,因为函数foo
和类foo
之间没有名称冲突。
但是,如果您包含“typedef class foo foo;
”,则会收到编译时错误,而不是行为中的无声差异。
答案 2 :(得分:6)
亚当提供了这样做的正确理由,但对于你的问题“这是值得的麻烦”,我会给出一个响亮的“不!”。可能的问题代码:
class SomeClass { ... };
int SomeClass;
稍后某人说:将会被抓住
SomeClass sc;
不可否认,编译器将指向“错误”行,但是这种事情很少发生(我认为我从未在实际代码中看到它)它无法证明一个近乎多余的森林类型定义
答案 3 :(得分:0)
看起来评论试图说明typedef使符号SomeClass全局化,以防止任何人声明一个隐藏原始SomeClass同名的本地对象。
我用VC6尝试了这个(不是我所知道的真正的C ++编译器,但是我有最好的ATM),而且似乎并没有做太多。 SomeClass仍然被具有相同名称的本地声明隐藏。也许它会改变某些编译器的错误消息的内容,使其更有用。
答案 4 :(得分:0)
在我看来,你的同事可能没有完全从毕业毕业。
在C语言中,如果您声明struct foo {int a;};
,则您没有任何可以调用foo
的内容,而是struct foo
。因此,将struct foo
键入foo
是很常见的。
这在C ++中有所改变,原因应该是相当明显的。
答案 5 :(得分:0)
要么是真的破坏了编译器,要么是某人不知道他们做了什么,或者我认为是这样。
答案 6 :(得分:-2)
我理解的概念 标记和标记的不同名称空间 标识符存在,但这是 真的很值得麻烦 打字吗?
没有