类定义后是否允许类声明? [英] Is a class declaration allowed after a class definition?
问题描述
我刚刚阅读了此答案,这完全让我感到困惑.
I just read this answer, and it completely puzzles me.
我一直认为类声明可以出现很多次,并且只需要定义一次就可以了,例如:
I was always thinking a class declaration can appear many times, and only the definition has to exist only once, like:
/*class Class {*/
class A; // (1) forward declaration
class A { // (2) definition, only once
int m;
};
class A; // (3) declaration again, legal?
class A a; // (4) declaration again, legal?
/*};*/
从链接的答案中获取答案:(3)(和(4)?)是非法的,如果上面的代码 嵌套在一个类中 (class Class
内.)
From the linked answer: (3) (and (4)?) is illegal if the code above is nested inside a class (definition and declarations of class A
are nested inside class Class
).
在 cppreference 上,我找到了上述示例, 未嵌套 :
On cppreference, I found an example of the above, not nested:
struct s { int a; };
struct s; // does nothing (s already defined in this scope)
void g() {
struct s; // forward declaration of a new, local struct "s"
// this hides global struct s until the end of this block
s* p; // pointer to local struct s
struct s { char* p; }; // definitions of the local struct s
}
请参阅第二行.
问题:鉴于在类内是非法的,因此我的示例代码和上面的cppreference示例是否合法,而 not 嵌套在类内是否合法?或更笼统地说:类声明何时可以遵循定义(例如,它如何在名称空间内)?如果合法,为什么会有区别?
Question: Given that it is illegal inside a class, is my example code, and the cppreference example above, legal when not nested inside a class? Or more generally: When can a class declaration follow a definition (how is it inside namespaces for example)? If it is legal, why is there a difference?
推荐答案
来自[basic.def]:
From [basic.def]:
声明(第7条)可以在翻译单元中引入一个或多个名称或重新声明以前声明引入的名称.
来自[class.name]:
From [class.name]:
仅由 class-key标识符组成的声明;或者是在当前作用域中名称的重新声明,或者是将标识符作为类名称的前向声明.它介绍了类名 进入当前范围.
A declaration consisting solely of class-key identifier; is either a redeclaration of the name in the current scope or a forward declaration of the identifier as a class name. It introduces the class name into the current scope.
因此通常这样做是合法的. [class.mem]中只有一个例外:
So it's generally legal to do this. There's just the one exception in [class.mem]:
成员规范中的成员不得两次声明, 除了可以声明嵌套类或成员类模板然后再定义,以及可以使用 opaque-enum-declaration 引入枚举并随后使用 enum-specifier重新声明枚举之外.
A member shall not be declared twice in the member-specification, except that a nested class or member class template can be declared and then later defined, and except that an enumeration can be introduced with an opaque-enum-declaration and later redeclared with an enum-specifier.
在命名空间范围内完全可以,在类范围内是不允许的.
Perfectly OK in namespace scope, not allowed in class scope.
为什么呢?好吧,这条规则使您可以转发"声明您通常需要执行的所有操作所需的所有类:
As to why? Well, this rule let's you "forward" declare all the classes you need everywhere you would typically be allowed to do so:
// a.h
struct C;
struct A {
C* c;
};
// b.h
struct C;
struct B {
C& c;
};
无需担心有人实际上包括完整的声明并为您破坏一切:
without having to worry about somebody actually including the full declaration and breaking everything for you:
// d.h
#include "c.h"
#include "a.h" // now C was already declared!
#include "b.h" // and here too!
struct D { ... };
在类定义内 并不是什么大问题.它不能精确地跨越多个文件.因此,无法重新声明嵌套类型实际上无法实现任何目的.
This isn't so much of a concern within a class definition. It can't exactly span multiple files. So the inability to redeclare nested types doesn't actually achieve anything.
这篇关于类定义后是否允许类声明?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!