C++ 您真的需要C+;中的main()吗+;?

C++ 您真的需要C+;中的main()吗+;?,c++,C++,据我所知,在创建全局对象时,可以启动构造函数中的所有操作。那么,你真的需要C++中的主函数吗?还是仅仅是遗留的? 我可以理解,这样做可能被视为不好的做法。我只是好奇而已。 < P>如果你想在托管C++实现中运行你的程序,你需要一个主< /Cuff>函数。事情就是这样定义的。当然,如果你愿意的话,你可以把它空着。在技术方面,链接器希望解析运行时库中使用的main符号(它不知道您是否有意省略它-它仍然会发出调用)。如果标准规定main是可选的,那么实现当然可以提出解决方案,但这需要在并行世界中实现

据我所知,在创建全局对象时,可以启动构造函数中的所有操作。那么,你真的需要C++中的主函数吗?还是仅仅是遗留的?
我可以理解,这样做可能被视为不好的做法。我只是好奇而已。

< P>如果你想在托管C++实现中运行你的程序,你需要一个<代码>主< /Cuff>函数。事情就是这样定义的。当然,如果你愿意的话,你可以把它空着。在技术方面,链接器希望解析运行时库中使用的
main
符号(它不知道您是否有意省略它-它仍然会发出调用)。如果标准规定
main
是可选的,那么实现当然可以提出解决方案,但这需要在并行世界中实现

如果您使用“在我的全局对象的构造函数中开始执行”,请注意,您会遇到许多与在不同转换单元中定义的命名空间范围对象的构造顺序相关的问题(那么什么是入口点呢?答案是:您将有多个入口点,并且首先执行哪个入口点是未指定的!)在C++03中,您甚至不能保证
cout
的构造是正确的(在C++0x中,您可以保证在任何代码尝试使用它之前,只要前面有一个include of

如果您在
::main
中正确地开始执行操作,您就不存在这些问题,也不需要解决它们(这可能非常棘手)


但是,如注释中所述,有几个系统通过让用户说出在
main
中实例化的类的名称来隐藏
main
。这与下面的示例类似

class MyApp {
public:
  MyApp(std::vector<std::string> const& argv);

  int run() {
      /* code comes here */
      return 0;
  };
};

IMPLEMENT_APP(MyApp);

这不存在上述未指定的构造顺序的问题。它们的好处是,它们与不同形式的更高级别的入口点一起工作。例如,Windows GUI程序在
WinMain
函数中启动-
IMPLEMENT\u APP
可以在该平台上定义这样的函数。

有些实现不可能实现全局对象,或者这些对象不可能使用非平凡构造函数(特别是在移动和嵌入式领域).

如果要构造多个全局对象,则无法保证哪个构造函数将首先运行。

一般来说,应用程序需要一个入口点,而
main
就是该入口点。全局对象的初始化可能在
main
之前发生,这一事实与此无关。如果编写控制台或GUI应用程序必须有一个
main
才能链接,唯一的好做法是让该例程负责应用程序的主要执行,而不是出于奇怪的意外目的使用其他功能。

如果您正在构建静态或动态库代码,则无需定义
main
你自己,但你仍然会在某些程序中运行它。

< P>。从C++标准的角度来看,是的,仍然是需要的。但是我怀疑你的问题与此不同。

但我认为按照你的想法去做会带来太多的问题

例如,在许多环境中,
main
的返回值是作为整体运行程序的状态结果给出的。这很难从构造函数中复制。当然,一些代码仍然可以调用
exit
,但这似乎像是使用
goto
,并且会跳过对堆栈上的任何东西。您可以尝试通过抛出一个特殊异常来修复问题,以生成除
0
之外的退出代码

但是,您仍然会遇到全局构造函数的执行顺序没有定义的问题。这意味着在全局对象的任何特定构造函数中,您将无法对是否存在任何其他全局对象做出任何假设

你可以试着通过说每个构造函数都有自己的线程来解决构造函数顺序问题,如果你想访问任何其他全局对象,你必须等待条件变量,直到它们说它们被构造。这只是要求死锁,而这些死锁将很难调试。你还需要e哪个线程以特殊的“程序返回值”异常退出将构成整个程序的实际返回值的问题

如果你想摆脱
main
,我认为这两个问题是致命的


我想不出有哪种语言没有与
main
基本等价的语言。例如,在Java中,有一个外部提供的类名,它是
main
静态函数。在Python中,有
\uu main
模块。在
perl
中,有您在命令行上指定的脚本。

是的!您可以取消main

免责声明:你问这是否可能,而不是是否应该这样做。这是一个完全不受支持的坏主意。我自己做过这件事,原因是我不想参与,但我不推荐。我的目的不是摆脱main,但它也可以做到这一点

基本步骤如下:

  • 在编译器的CRT源目录中找到
    crt0.c
  • crt0.c
    添加到项目中(副本,而不是原件)
  • crt0.c
    中查找并删除对main的调用
  • 让它编译和链接可能很困难;困难程度取决于哪个编译器和哪个编译器版本

    已添加

    我刚刚用VisualStudio2008做的,所以他
    #define IMPLEMENT_APP(AppClass) \
      int main(int argc, char **argv) { \
        AppClass m(std::vector<std::string>(argv, argv + argc)); \
        return m.run(); \
      }
    
    #include <iostream>
    
    class App
    {
        public: App()
        {
            std::cout << "Hello, World! I have no main!" << std::endl;
        }
    };
    
    static App theApp;