为什么在 C++ 中的 class 指针声明中使用 'struct' 关键字
Why use 'struct' keyword in class pointer declaration in C++
在 C++ 中声明 class 指针变量时,何时以及为什么要使用 'struct' 关键字?
我在嵌入式环境中看到过这个,所以我怀疑这是 C 的某种保留。我已经看到很多关于在声明结构对象时何时使用 'struct' 关键字的解释因为它与 C 中的名称空间有关 (here),但我找不到任何人谈论为什么在声明 class 指针变量时可能会使用它。
示例,在 CFoo.h 中:
class CFoo
{
public:
int doStuff();
};
inline Foo::doStuff()
{
return 7;
}
后来在另一个class:
void CBar::interesting()
{
struct CFoo *pCFoo;
// Go on to do something interesting with pCFoo...
}
很少有这样做的理由:它是 C 的失败者,在这种情况下,程序员只是多愁善感——也许是为了提高可读性。也就是说,它可以用来代替前向声明。
在某些情况下,您可能需要消除歧义,但此处并非如此。一个需要消除歧义的例子是
class foo{};
int main()
{
int foo;
class foo* pf1;
struct foo* pf2;
}
请注意,您可以互换使用 class
和 struct
。您也可以使用 typename
,这在使用模板时很重要。以下是有效的 C++:
class foo{};
int main()
{
class foo* pf1;
struct foo* pf2;
typename foo* pf3;
}
这样做有两个原因。
第一个是我们是否要使用详细名称在范围内引入新类型。也就是这个定义
void CBar::interesting()
{
struct CFoo *pCFoo;
// Go on to do something interesting with pCFoo...
}
新类型 struct CFoo
在尚未声明的范围内引入。指针可能指向不完整的类型,因为指针本身就是完整的类型。
第二种情况是 class 的名称被函数或变量的声明隐藏。在这种情况下,我们再次需要使用详细的类型名称。
这里有一些例子
#include <iostream>
void CFoo( const class CFoo * c ) { std::cout << ( const void * )c << '\n'; }
class CFoo
{
public:
int doStuff();
};
int main()
{
class CFoo c1;
return 0;
}
或
#include <iostream>
class CFoo
{
public:
int doStuff();
};
void CFoo( void ) { std::cout << "I am hidding the class CGoo!\n"; }
int main()
{
class CFoo c1;
return 0;
}
在 C 中,两种不同的风格是最常见的:
typedef struct { ... } s;
变量声明为 s name;
.
struct s { ... };
变量声明为 struct s name;
在C++中你不需要typedef
省略struct
关键字,所以前一种风格更符合C++类型系统和类,使得它是 C++ 中最常见的样式。
但是在 C++ 中,当您真正想要首先使用 struct
而不是 class
的情况并不多 - 结构本质上是 类 所有成员 [=默认为 30=]。
这样做的原因可能很简单,因为除了宣布 CFoo
命名一个类型外,不需要包含其内容不需要的头文件。这通常通过前向声明来完成:
class CFoo;
void f(CFoo*);
但也可以即时完成:
void f(struct CFoo*);
在 C++ 中声明 class 指针变量时,何时以及为什么要使用 'struct' 关键字?
我在嵌入式环境中看到过这个,所以我怀疑这是 C 的某种保留。我已经看到很多关于在声明结构对象时何时使用 'struct' 关键字的解释因为它与 C 中的名称空间有关 (here),但我找不到任何人谈论为什么在声明 class 指针变量时可能会使用它。
示例,在 CFoo.h 中:
class CFoo
{
public:
int doStuff();
};
inline Foo::doStuff()
{
return 7;
}
后来在另一个class:
void CBar::interesting()
{
struct CFoo *pCFoo;
// Go on to do something interesting with pCFoo...
}
很少有这样做的理由:它是 C 的失败者,在这种情况下,程序员只是多愁善感——也许是为了提高可读性。也就是说,它可以用来代替前向声明。
在某些情况下,您可能需要消除歧义,但此处并非如此。一个需要消除歧义的例子是
class foo{};
int main()
{
int foo;
class foo* pf1;
struct foo* pf2;
}
请注意,您可以互换使用 class
和 struct
。您也可以使用 typename
,这在使用模板时很重要。以下是有效的 C++:
class foo{};
int main()
{
class foo* pf1;
struct foo* pf2;
typename foo* pf3;
}
这样做有两个原因。
第一个是我们是否要使用详细名称在范围内引入新类型。也就是这个定义
void CBar::interesting()
{
struct CFoo *pCFoo;
// Go on to do something interesting with pCFoo...
}
新类型 struct CFoo
在尚未声明的范围内引入。指针可能指向不完整的类型,因为指针本身就是完整的类型。
第二种情况是 class 的名称被函数或变量的声明隐藏。在这种情况下,我们再次需要使用详细的类型名称。
这里有一些例子
#include <iostream>
void CFoo( const class CFoo * c ) { std::cout << ( const void * )c << '\n'; }
class CFoo
{
public:
int doStuff();
};
int main()
{
class CFoo c1;
return 0;
}
或
#include <iostream>
class CFoo
{
public:
int doStuff();
};
void CFoo( void ) { std::cout << "I am hidding the class CGoo!\n"; }
int main()
{
class CFoo c1;
return 0;
}
在 C 中,两种不同的风格是最常见的:
typedef struct { ... } s;
变量声明为s name;
.struct s { ... };
变量声明为struct s name;
在C++中你不需要typedef
省略struct
关键字,所以前一种风格更符合C++类型系统和类,使得它是 C++ 中最常见的样式。
但是在 C++ 中,当您真正想要首先使用 struct
而不是 class
的情况并不多 - 结构本质上是 类 所有成员 [=默认为 30=]。
这样做的原因可能很简单,因为除了宣布 CFoo
命名一个类型外,不需要包含其内容不需要的头文件。这通常通过前向声明来完成:
class CFoo;
void f(CFoo*);
但也可以即时完成:
void f(struct CFoo*);