C++ 前向声明静态函数c++;
我想在另一个文件中向前声明一个类的静态成员函数。我想做的事情如下所示: BigMassiveHeader.h:C++ 前向声明静态函数c++;,c++,C++,我想在另一个文件中向前声明一个类的静态成员函数。我想做的事情如下所示: BigMassiveHeader.h: class foo { static void init_foos(); } Main.cpp: class foo; void foo::init_foos(); int main(char** argv, int argc) { foo::init_foos() } 此操作失败,出现“错误C2027:使用未定义的类型'foo'” 有没有一种方法可以完成我想做的事
class foo
{
static void init_foos();
}
Main.cpp:
class foo;
void foo::init_foos();
int main(char** argv, int argc)
{
foo::init_foos()
}
此操作失败,出现“错误C2027:使用未定义的类型'foo'”
有没有一种方法可以完成我想做的事情,而不必使init_foos成为一个免费函数,或者包括BigMassiveHeader.h?(BigMassiveHeader.h明显影响编译时,并且包含在所有地方。)不,您需要包含用于编译时的头。对不起
如果必须,请使用自由函数,或拆分类。您不能转发类的声明成员,无论它们是否是静态的。您不能转发类的声明成员,但可以在该命名空间内创建命名空间和函数,然后转发声明
namespace nsfoo
{
void init_foos();
}
您的类如果需要,可以与此函数相关联。 如果您有<代码> BigMassiveHeader <代码>,您应该考虑将其分割成几个<代码> SimultCaseAdvests<代码>。如果您想表示许多类和函数在语义上属于同一个名称空间,可以将它们放在同一个名称空间中。你可以提供一个包含所有小标题的方便标题。 < P>你不能在C++中部分声明类,所以你必须把类的声明放在它自己的、较小的头或……/P>中。 在文件中包含
BigMassiveHeader.h
,并使用预编译的头文件。
VisualC++方式:或者GCC方式:.< /p> 我知道这不是问题的要点,但是如果BigMaSeMeHealth.h不太可能随着时间的推移而变化,你应该看看< P>作为第一次重构,我会使用一个调用静态函数的自由函数。您的main方法并不是被多次调用,因此您不会注意到额外的调用,这使得对现有代码的更改最少 当然,你实际上并没有说你想做什么,只是说你想做什么。如果您试图在应用程序启动时调用
init\u foos
,请使用静态对象初始化,而不是在main中调用它。如果您试图做的是在创建所有静态对象之后调用init\u foos
,那么它就更复杂了
所谓静态对象初始化,我指的是在.cpp文件中包含这样的内容,该文件可以访问init\u foos
的定义。将其设置为好友并init_foos
private以防止多次呼叫:
struct call_init_foos {
call_init_foos () { foo::init_foos(); }
} call_init_foos_on_startup;
要转发类的单个方法的声明,必须将该方法声明为类的一部分(实际上是这样) 例如,在您的情况下,添加到main.cpp:
class foo
{
public:
static void init_foos();
}
它不是最漂亮的,但它可以让您不用包含整个标题。它甚至不是
foo::init_foos()的前向声明但是,C++语言中没有“向前声明”这个术语。一般来说,“向前声明”通常意味着“声明而不定义”。考虑到这一点,可以“前向声明”成员函数。每次定义类时,都是“正向声明”其[非内联]成员函数。正确的答案是:如果不定义类,就不能声明类成员。詹姆斯·麦克内利斯(James McNellis)删除的答案实际上是正式正确的。@AndreyT:标准的第27.2节标题为“转发声明”,TC++PL特别版中有一个索引项。@David Thornley:好的,很公平。我仍然坚持这个词是非正式使用的。更准确地说,它描述的是这些声明的目的,而不是声明本身的形式属性。@AndreyT我同意你的观点,“转发声明”只是非正式地使用(与“原型”相同)。但我认为James的回答在形式上并不正确,因为静态成员函数可以在类外很好地声明(如果该声明是一个定义,或者如果该声明发生在友元函数声明中的另一个类内)。只有它的第一个声明必须出现在类内部。无论是在.cpp中还是在BigHeader.h中包含代码都不会产生影响。毕竟,您正在使用#include-guards或#pragma-once-so-BigHeader.h只编译一次,对吗?@Kyte-include-guards将BigHeader.h限制为每个包含它的翻译单元一次。如果它包含在许多源文件中,则需要多次编译。因此,是否可以将class foo
的定义拆分为另一个头文件?我们非常清楚这一点。BigMassiveHeader的重构是我们从前辈那里继承下来的一点技术债务,我们正在分期付款。事实上,这是该努力的一部分。