主要功能是什么? 我正在寻找一个最佳的实践技巧,它是使用C++的程序的主要功能。目前我认为有两种方法是可行的。(尽管这些方法的“边际”可以任意接近)

主要功能是什么? 我正在寻找一个最佳的实践技巧,它是使用C++的程序的主要功能。目前我认为有两种方法是可行的。(尽管这些方法的“边际”可以任意接近),c++,coding-style,main,C++,Coding Style,Main,1:编写一个“Master”类,该类接收传递给main函数的参数,并在该“Master”类中处理完整的程序(当然,您还可以使用其他类)。因此,主功能将减少到最少行 #include "MasterClass.h" int main(int args, char* argv[]) { MasterClass MC(args, argv); } 2:当然,使用用户定义的对象在主函数中编写“完整”程序!然而,也涉及到全局函数,主函数可能会变得有些大 我正在寻找一些如何在C++中编写程序主要功能的一般

1:编写一个“Master”类,该类接收传递给main函数的参数,并在该“Master”类中处理完整的程序(当然,您还可以使用其他类)。因此,主功能将减少到最少行

#include "MasterClass.h"
int main(int args, char* argv[])
{
MasterClass MC(args, argv);
}
2:当然,使用用户定义的对象在主函数中编写“完整”程序!然而,也涉及到全局函数,主函数可能会变得有些大


我正在寻找一些如何在C++中编写程序主要功能的一般指南。我遇到这个问题是因为我尝试为第一种方法编写了一些单元测试,这有点困难,因为大多数方法都是私有的。

您的第一种方法非常常见,尽管该类往往被命名为“Application”(或至少包含“Application”一词)这样做。

我将在主例程中分析流程的参数,然后通过传递比argc和argv更可读的参数来创建一个类实例。

您描述的是两种“极端”方法,我觉得这两种方法都不对。无论是使用单一God函数,还是使用单一God函数,都不是实现任何真正用途的非平凡程序的正确方法

main()
中调用
MasterClass
也可以(尽管我更喜欢分区功能,例如在
main()
中执行任何命令行特定的处理,以便将
MasterClass
与命令行参数的细节分离)。但是,如果该类很难进行单元测试,那么这是设计问题的一个标志,通常解决方案是将其部分或全部可测试功能委托给其他类,在这些类中,可以通过公共接口轻松地进行单元测试

您的第二种方法对于单元测试来说也可能有问题,所以您应该努力从中吸取经验(最好是这样),使细粒度单元测试成为可能

因此,您想要达到的最佳状态介于两个极端之间,受使代码可测试的要求的限制

值得考虑的是如何总体构造程序,而不仅仅是在
main()
的上下文中。基本思想是将其划分为“块”(类和方法),这些块是

  • 足够小,易于理解、测试和维护
  • 逻辑上连贯

通常,我执行必要的特定于平台的设置操作,然后委托给对象。一个对象在一个函数上没有什么好处,但是对象可以从接口继承,如果你说使用独立于接口的库,它可以使用回调的接口实现。

第一:我很少使用C++,但是我认为这不是一个语言特定的问题。 嗯,我想这可以归结为除了一些实用性问题之外的品味。


我个人倾向于使用layout#1,但不要将命令行解析例程放在MasterClass中。对我来说,这显然属于主流。MasterClass应该获得解析的参数(整数、文件流等)。

通常我在应用程序的命名空间中调用一个主函数(具有相同的签名):

namespace current_application {
    int main( int argc, char **argv ) {
        // ...
    }
}
int main( int argc, char **argv ) {
    return current_application::main( argc, argv );
}
然后我通常使用实际的main(名称空间中的一个)来初始化应用程序方面的内容:

  • 设置标准输入/输出/错误的区域设置)

  • 解析应用程序参数

  • 在我的主类的对象上实例化(如果存在)(类似于
    QApplication

  • 调用main函数(如果存在)(类似于
    QApplication::run

通常更喜欢在那里添加
try
catch
块,以便在崩溃时打印更多调试信息



然而,所有这些都是高度主观的;这是你的编码风格的一部分。

为什么你会有一门大师课?它的单一责任领域是什么


“Master”或“application”类往往会变成一个大的blob,完成太多不同的事情。归根结底,这有什么意义?它给你买了什么

为什么不使用main功能来提供此main功能?在
main
中定义高级应用程序生命周期。它接受一些命令行参数并对其进行解析(最好是将其委托给另一个函数或类),然后调用一些设置功能,然后可能会在执行某些清理之前进入某种主循环。总而言之,这可能会给你一个大概10-15行的主功能,但可能不会超过这个。它应该尽可能多地委托给其他类和函数。因此,
main
本身保持简短和甜蜜,但仍然有目的

将这种超高级流放入
main
意味着很容易找到,因为
main
是您的起点。如果您想理解代码,就要从这里开始查找。所以,把读者在试图理解代码时想要知道的东西放进去


当然,你可以把所有这些都放在一个“主类”中,除了满足所有认为“所有东西都必须在一个类中”的Java luddites之外,你什么也得不到。我看不出这有什么好处。一种中间路线的方法,稍微倾向于大师级模型,对我来说是可行的。主类对象通常是巨大的,最好在堆上创建。我的主要功能是创建对象并处理任何错误
class MasterClass {
public:
static MasterClass* CreateInstance( int argc, char **argv );
    // ...
}

int main(int argc, char** argv)
{
    try
    {
         MasterClass mc = MC::CreateInstance(argc, argv);
    }
    catch(...)
    {
        // ...
    }
}
STATUS LNPUBLIC AddInMain(HMODULE hModule, int argc, char far *argv[])
{
     MasterClass mc = MC::CreateInstance(argc, argv);
     while(/* wait for scheduler to give control */)
     {
          STATUS s = mc->RunForTimeSlice();
          if (s != SUCCESS)
               break;
     }
     // clean up
}