使用 typedef 和匿名类定义与传统类定义的等价性 [重复]
Posted
技术标签:
【中文标题】使用 typedef 和匿名类定义与传统类定义的等价性 [重复]【英文标题】:Equivalancy of using typedef and an anonymous class definition to conventional class definition [duplicate] 【发布时间】:2012-10-19 19:21:46 【问题描述】:可能重复:Difference between ‘struct’ and ‘typedef struct’ in C++?
this question 的回答让我想知道以下几点:
我假设定义一个类如下:
typedef class int i; C;
将完全等同于以传统方式定义它:
class C
int i;
;
这个假设正确吗?
【问题讨论】:
@ecatmur 我猜它是(除了可以忽略的类与结构差异)。 【参考方案1】:在这个孤立的例子中,它们在功能上是相同的,至少从外部看是这样。
但是有区别。特别是一个实例,您不能为struct
或class
声明以这种方式声明的构造函数,因为class
未命名。同样,您不能声明任何涉及类名的函数。以下是一些示例:
typedef class
public:
Gizmo() : n_(42) ; // NOT OK
~Gizmo();
Gizmo& operator<<(int n);
private:
int n_;
Gizmo;
你也不能转发声明一个匿名类:
class Gizmo;
在 C++ 中,我从未见过typedef
匿名struct
或class
比简单地声明class
或struct
更可取的情况。在某些情况下,传统方法绝对是首选。这个故事的寓意是:不要在 C++ 中使用typedef class Name;
。它不会给你带来任何东西,却会让你付出一些代价。
【讨论】:
“你不能声明构造函数”——或者析构函数、复制/移动赋值运算符或任何涉及类名的东西,显然。typedef struct ... name
主要出现在必须与 C'99 之前的库保持二进制兼容性的代码中,其中类型空间和标记空间不同。 (例如,win32 API 或 X11 API)
有趣的是,您可以做的一件事是定义类外的成员函数,因为您可以在此处使用 typedef-name 作为类名.另请参阅this question。
虽然还有其他好的/正确的答案,但我接受了这个答案,因为我应该看到整个“匿名定义意味着需要名称的东西不起作用”方面。
它确实给你买了一件事,那就是它可以防止任何人命名一个函数 Name
(这可能会无意中干扰使用 Name()
构建临时函数的尝试)。请参阅 Pubby 的回答。但是不使用typedef class Name;
的建议仍然是合理的,因为如果您想要该功能,您可以通过typedef class Name Name;
获得它【参考方案2】:
这里还有一个区别:后者可以前向声明,而前者不能。
【讨论】:
【参考方案3】:从实际的角度来看是的,因为标准说(9.1/5)
命名类类型或其 cv 限定版本的 typedef-name (7.1.3) 也是 > 类名。如果使用命名 cv 限定类类型的 typedef-name,其中 需要类名,忽略 cv 限定符。
7.1/3 说:
使用 typedef 说明符声明的名称成为 typedef-name。 在其声明范围内,typedef-name 在语法上是 等效于关键字并命名与 第 8 节中描述的标识符。因此 typedef-name 是 另一种类型的同义词。
从理论上讲不会,因为您可以(实际上我看到人们已经拥有)根据使用的版本起草有效或无效的程序,因为 7.1/3 继续从我切断它的地方说:
一个 typedef-name 确实 不要像类声明 (9.1) 或枚举声明那样引入新类型。
【讨论】:
所以在这种情况下是的,一般情况下不是。 +1 从标准向我展示。【参考方案4】:我相信这是一个重复的问题(找不到),但如果不是,请注意编译:
class C
int i;
;
void C()
class C x;
虽然这不会:
typedef class
int i;
C;
void C()
C x;
名称空间不同。
【讨论】:
你说得对,后者无法编译,而且它们似乎占用了不同的命名空间,很酷。 +1 向我展示了你可以拥有一个类和一个函数共享同名(这只是我下意识地避免做的事情)。【参考方案5】:它们不相等。特别是,
int main()
class C c;
只会编译两个定义之一。
【讨论】:
以上是关于使用 typedef 和匿名类定义与传统类定义的等价性 [重复]的主要内容,如果未能解决你的问题,请参考以下文章
模板typedef与std :: vector有自定义分配器