这两种方法有什么区别?
有时当我遇到编译时错误时抱怨编译器无法识别 函数签名中的一些类类型,如果我在相应的变量前添加关键字“class”,它总能解决这种编译时错误。
例如,如果编译器无法识别
中的 客户端 类型void recv( Client * c )
然后我将其改为
void recv( class Client * c )
问题解决了。
对不起,我无法想出一个具体的例子,因为我随机提出了这个问题。
答案 0 :(得分:12)
在类型参数声明中使用关键字class,struct,enum称为详细类型说明符。它在声明函数的范围中引入了新类型。 它类似于前向声明。
还有另一种使用这种声明。例如,如果对象的名称或函数名称隐藏具有相同名称的类或枚举。例如
struct A {};
A A; // now A is seen as an identifier of the object
void f( struct A );
答案 1 :(得分:1)
在这种情况下
void recv(Client * c)
编译器查找Client
的声明。如果找不到,就会出错。您可以通过前向声明解决它,如下所示
class Client;
void recv(Client * c)
虽然我从未见过第二种情况,但看起来这也是在这里声明类客户端。
答案 2 :(得分:1)
如果需要在参数前加上class
,则表示编译器尚未知道名为Client
的类。采取以下设计的例子:
int main(int argc, char *argv[])
{
MyClass m;
return 0;
}
class MyClass
{
};
因为MyClass
是在main函数之后声明的,所以main函数在尝试创建变量MyClass
时不知道名为m
的类,并且您的程序将拒绝编译。
要解决此问题,您通常会使用前向声明:
class MyClass; // <-- Forward declare MyClass.
int main(int argc, char *argv[])
{
MyClass m;
return 0;
}
class MyClass
{
};
在您的情况下,在函数参数的类型之前使用class
关键字基本上是为您声明类名。
答案 3 :(得分:1)
编译器必须知道函数参数的类型。由于您显然没有提供定义,例如通过包含Client
的标题,您必须提供前向声明。这就是你在第二个例子中做的(以一种不寻常的方式),因此编译器知道,Client是一个类。由于您只使用指针,因此声明就足够了,此时您不需要定义。