类声明括号后的分号


82

在C ++类中,为什么在右花括号后加分号?我经常忘记它并得到编译器错误,从而浪费时间。在我看来似乎有点多余,事实并非如此。人们是否真的在做以下事情:

class MyClass
{
.
.
.
} MyInstance;

从结构和枚举的C兼容性角度来看,但是由于类不是C语言的一部分,我想它主要是在类似声明结构之间保持一致性。

我一直在寻找的是与设计原理相关的东西,而不是能够更改任何东西,尽管良好的代码完成IDE可能会在编译之前就将其捕获。


4
这可能帮助:cpptalk.net/...
迈克尔·哈伦

@Michael,感谢您的链接。从历史的角度来看,这是有道理的,如果C ++允许所有C语法,并且C ++类与struct是同义的,则在类末尾留有必要的分号。
SmacL

3
@Brian,是的,很严重的问题。我知道我必须忍受它,但是我对设计和实现背后的理由感到好奇。
SmacL

好的,但是您可能应该编辑问题以包含所需的设计依据。实际上,它鼓励人们提出诸如“为什么用花括号”之类的问题?:)您可能对阅读Stroustrup的C ++设计与演化感兴趣,尽管在课程结束时它比分号更重要。
Brian Neal

@Brian,很公平,对于是否对其进行维基化是一个临界点。在大型构建中,在经常使用的标头中省略分号后,提出了此问题。我花了半个小时,所以去了SO。根据您的建议修改了问题。
SmacL

Answers:


47

语言需要在类型声明中的右花括号后加分号。自最早的C版本以来就是这样。

是的,确实确实有人在做您刚刚在那儿张贴的声明。这对于在方法内部创建作用域类型很有用。

void Example() {
  struct { int x; } s1;
  s1.x = 42;

  struct ADifferentType { int x; };
}

在这种情况下,我认为很清楚为什么需要分号。至于为什么在不确定的头文件中更一般的情况下需要它,我不确定。我的猜测是,这是历史悠久的,并且这样做是为了简化编译器的编写。


为什么不指定MyInstance就不能创建作用域类型?当您组合两个动作时,它会显得很奇怪:声明新类型和声明新变量。
Mykola Golubyev 09年

@Mykola可以同时做。请参阅我添加的示例
JaredPar

70

所述链接由@MichaelHaren提供似乎提供的根本原因。分号(如其他人所指出的)是从C继承的。但这并不能解释为什么C首先使用它。讨论包括以下示例:

struct fred { int x; long y; }; 
main() 
{ 
  return 0; 
} 

除非另外声明,否则较旧的C版本具有函数的隐式int返回类型。如果我们;在结构定义的末尾省略,则不仅要定义新的类型fred,还要声明main()它将返回的实例fred。即代码将被解析为:

struct fred { int x; long y; } main()
{ 
  return 0; /* invalid return type, expected fred type */
} 

1
是的,隐式int返回类型将在此处影响所有内容。漂亮的宝石
Gaspa79 '19

17

我想这是因为类是声明,即使它们需要大括号进行分组也是如此。是的,有一个历史论点,因为在C语言中您可以

struct
{
  float x;
  float y;
} point;

您应该在C ++中能够执行类似的操作,使class声明以相同的方式运行是有意义的。


10

这是短的

class MyClass
{
.
.
.
};

// instance declaration
MyClass MyInstance;  // semicolon here

类声明的花括号后的分号实际上是过分的,但这就是C ++的定义方式。始终需要变量声明后的分号,这是有意义的。


1
那么,C ++在每个声明之后都需要用分号吗?
Loai Nagati,2009年

1
请注意,用这种方法,您不能创建匿名类的对象,而可以用另一种方法。
凯文

5

我不使用此类声明

class MyClass
{
.
.
.
} MyInstance;

但是在这种情况下,我可以理解为什么分号在那里。
因为就像int a;-变量声明。

可能是为了保持一致性,您可以省略“ MyInstance”分号。


3

struct出于兼容性原因,需要a之后使用它,您希望如何:

struct MyStruct { ... };
class  MyClass  { ... }    //inconsistency

1
但是呢namespace myNamespace { ... } // inconsistent but valid
克里斯K,

3

在C / C ++中;是语句终止符。所有语句以;终止;以避免歧义(并简化解析)。在这方面,语法是一致的。即使一个类声明(或与此有关的任何块)长多行并用{}分隔,它仍然只是一个语句({}是该语句的一部分),因此需要以;结尾;(;不是分隔符/分隔符)

在你的例子中

class MyClass{...} MyInstance;

是完整的声明。一个人可以在一个语句中定义已声明类的多个实例

class MyClass{...} MyInstance1, MyInstance2;

这与在单个语句中声明基本类型的多个实例完全一致:

int a, b, c;

之所以不经常看到这样的类和实例的声明,是因为实例只能吗?是一个全局变量,除非它们是静态和/或普通旧数据结构,否则您实际上并不经常需要全局对象。


2
但是函数定义也是一条语句,但没有分号。
张佳鹏
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.