如何在C++类中实现一个“main”方法?

8
考虑以下内容:
static class EntranceClass {
public:
    static void RegisterSomething()
    {
    }

    static int main()
    {
        RegisterSomething();
        return 0;
    }
} // <-- Expected unqualified-id at the end

我遇到了以下错误:

expected unqualified-id at end of input main.cpp Problem

是否有解决方案?

11
C++ 和 Java 在这方面有所不同。在 C++ 中,你没有一个 "public static void main()",而只有一个在文件级别上放置的 "int main()"。 - Bill
7
你还需要在最后一个闭合大括号之后加上分号。 - Evan Teran
1
我不理解为什么这个问题一开始会受到欢迎。原帖作者试图做的事情a) 没有多少意义 b)与报告的错误原因没有任何关系。 - Karl Knechtel
意图是什么?将程序的主入口点设置为(静态)成员函数?与程序启动时的(自动)初始化有关的内容?程序启动时的初始化顺序? - Peter Mortensen
意图很重要。有些答案是好的猜测和解释,但如果没有实际意图,就不可能知道真正的答案应该是什么。也许原帖作者应该提供一些输入?他或她仍然活跃(“上周最后一次出现”)。 - Peter Mortensen
8个回答

30

main 只是 main。它只是一个函数:

class EntranceClass
{
    ...
}; // <-- Note the semicolon

int main()
{

}

9
需要强调在类声明的结尾需要使用分号。 - luke

12
该错误是指在类定义之前使用了static关键字 - 编译器期望在其后有一个变量名(因为在C++中不存在static class)。如果您想将static int EntranceMain::main(void)用作程序的入口点,则一种方法是告诉链接器,即提供该函数的完整装饰名称。这高度依赖于您使用的编译器和链接器,因此您需要参考它们的文档。但是使用它可能意味着您需要包含启动代码(例如CRT初始化)。请注意,这不太符合标准。

6
你不需要告诉连接器这个。你需要在全局层级做类似于 "int main() { return EntranceMain::main(); }" 的操作。否则,你就是在编写一个不可移植的 hack(可能会随着实现的任何更改而消失),而不是 C++。 - David Thornley
主函数是一个有点普通的方法名。 - call me Steve
“main”已经被其他人提到过了,这只是另一种方式。我并没有说这是最好的;如果您认为措辞不好,请随意编辑。 - Cat Plus Plus
这并不是真的,C++ 中是存在静态方法的。例如类成员 static int myFunction() 是完全合法的。 - RED SOFT ADAIR
1
我知道。我说的是“静态类”。 - Cat Plus Plus

10
根据标准,您没有编写真正的main函数。 第3.6.1节第3段: "在程序中不应使用(3.2)函数mainmain的链接(3.5)是实现定义的。声明maininlinestatic的程序是不合法的。名称main不受保留。[例如:成员函数、类和枚举可以称为main,其他命名空间中的实体也可以。]" 这意味着,通过声明一个成员函数main,您只是声明了一个成员函数。它没有特殊的意义,并且在类中调用某个函数并不意味着可以独立地调用整个类。如果将snicklefrazz替换为该函数名称和所有引用,则程序意义完全相同。 从风格上来说,snicklefrazz更好,因为它不会与标准的main函数产生任何可能的混淆。 第3.6.1节第1段:"程序必须包含一个名为main的全局函数,这是程序的指定起点。在自由环境中是否需要定义main函数是实现定义的。" 这意味着,除非您正在编写标准所称的自由环境(通常用于编写嵌入式系统),否则需要定义一个全局main函数,并且这是程序的起点。 在Java中,类可以有一个main方法,这是在调用类时程序开始执行的地方。但在C++中不这样实现。(而且,正如其他人提到的那样,一个类不能是静态的,并且一个类定义以分号结束。)

我想补充一下,在程序中第一个函数应该是“start”,当然只有在进程被加载器加载时才会执行,因此你基本上可以将任何函数声明为入口点,但你需要修改程序段。 - clockw0rk

7
您可能忘记在括号闭合后加上分号。

1

在我的看法中,将主函数放入一个类中似乎是一种可怕的编码风格,但如果你真的想这样做,我认为实现方式应该更像这样:

class Foo{
public:
    int main(){ return 0; };
};

Foo bar;

int Foo::main(){
    bar.main();
}

就像我之前所说的,这似乎是非常糟糕的编码风格。你最好在一个.hpp文件中构建你的类,然后将其链接到你的program_main.cpp中(通过#include "foo.hpp"),该文件包含了你可以调用该类的int main(){ return 0; }函数。


1
同意 - 那个程序员离开后,必须维护这个程序的人可真惨。 - MBillock

1

你可能正在寻找对象的构造函数

无论如何,尝试移除static


1
在C++中,您可以拥有“全局”的函数,即不是任何类的成员(Java术语中的“方法”)的函数。
默认情况下,C++程序的入口点是一个“全局”的main()函数,通常看起来像这样:
int main(int argc, char *argv[])
{
  // Do stuff
}
main()的参数允许您的程序接受命令行参数。它们可以像下面这样省略:
int main()
{
  // Do stuff
}

在这种情况下,您的程序不接受任何参数。当程序正常退出时,惯例是main()返回0。返回值为0以外的返回值通常表示错误。
在C++中没有静态类的概念。您可以拥有静态成员函数和数据成员,或静态全局变量(从C语言继承的不同静态含义)。
在类定义后需要分号。

1
你可能想添加一条关于备用主函数原型的注释:"int main()". - Bill

-1

你可以尝试的一个技巧是创建一个名为"BaseApp"的类,它从中派生出来,然后实现一个虚函数,该虚函数调用到真实版本。

class BaseApp
{
public:
   virtual void   EntryPoint() = 0;
   static  BaseApp* GetApp() { return this; }
};

然后只需从中派生一个类,实现一个EntryPoint(),并定义您的对象。

class SpecializedApp: public BaseApp
{
public:
   void EntryPoint() { ... }
};

SpecializedApp g_App;

然后,你有一个调用它的main()函数:

void main()
{
   BaseApp::GetApp()->EntryPoint();
}

这是一种方法,您可以将主函数作为一种通用的启动程序类型,根据链接方式调用不同的入口点。您可以在BaseApp之上拥有Win32类或标准C类。


2
一个静态成员函数不能使用'this',因为它根本没有对任何实例进行操作。 - Luc Touraille

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接