c++如何定义其他开发人员需要调用的常量函数顺序

c++ how to define constant function order that needs to be invoked for other developers

本文关键字:调用 顺序 函数 常量 开发 何定义 定义 其他 c++      更新时间:2023-10-16

我遇到的问题是,我有几个函数需要按照定义的顺序调用——顺序不可破坏。现在,在我完成代码之后,代码需要继续进行开发。我正在寻找一些方法来设置某种牢不可破的结构中的函数。例如,我有:

function_1() { //do some stuff ..} ;  // must be first  
function_2() { //do some stuff based on function_1()..};  // must be second 
function_3() { //do some stuff based on function_1() and function_2()..};;  // must be third 

它们都在main()应用程序函数下。

创建另一个用于公共访问的函数,以确保其他三个函数按正确顺序调用。为了防止这些函数在公共API中可见,可以将它们隐藏在未命名的名称空间中。

在您的标题中放入

 bool function_4();

在相应的翻译单元中,您创建了一个未命名的名称空间,以防止其他人看到这些函数

 namespace {
     bool function_1() {
     }
     bool function_2() {
     }
     bool function_3() {
     }
 }

并定义function_4

 bool  function_4() {
     return function_1() &&
            function_2() &&
            function_3();
 }

我想您有一些充分的理由不将这三个函数打包为一个函数。

在这种情况下,最简单的方法是管理所有三个功能之间共享的状态

static int function_status=0;    // shared status:  nothing was called 
function_1() { 
    if (status>0) 
       throw exception ("function_1 MUST be called first and only once");
    status=1;  // function_1 was called
    ...
}   
function_2() {
    if (status<1) 
       throw exception ("function_1 MUST be called before 2");
    else if (status>2) // I suppose function 2 could be called several times
       throw exception ("function_2 CANNOT be called after 3");
    status = 2;   
    ...
}
function_3() {
    if (status<2) 
       throw exception ("function_2 MUST be called before 3");
    else if (status==3) 
       throw exception ("function_3 CAN ONLY BE CALLED ONCE");
    status = 3; 
    ...
}

正如您所看到的,此状态使您有机会非常精确地检查执行流是否符合您想要的逻辑

您可以创建包装函数

bool execute()
{
    return function_1() && function_2() && function_3();
}

函数将按顺序调用,如果任何函数出现故障,它将短路。假设函数返回指示成功/失败的bool,如果函数返回true,则所有函数都成功完成,否则至少有一个函数失败。

对函数排序的简单情况是生成一个由用户调用的函数,该函数执行所有三个子函数。然而,这并不总是有效的。用户可能需要在呼叫CCD_ 5之前在CCD_ 4之后进行一些处理。在这种情况下,您需要某种额外的上下文,例如

class Context
{
   friend Function1, Function2, Function3;
   enum State 
   {
     f0, f1, f2, f3 
   } state;
public:
   Context() { state = f0; }
   ~Context() { if (state != f3) { ... may need to do stuff... }
}
void Function1(Context &ctxt)
{
   assert(ctxt.state == f0);
   ctxt.state = f1;
   ... 
}

void Function2(Context &ctxt)
{
   assert(ctxt.state == f1);
   ctxt.state = f2;
   ... 
}
void Function3(Context &ctxt)
{
   assert(ctxt.state == f2);
   ctxt.state = f3;
   ... 
}
int main()
{
   Context c;
   Function1(c);
   ...
   Function2(c);
   ...
   Function3(c);
   // c will be destroyed and check that state is f3.
}

您可以尝试的一种方法是让function_1()返回一个只有它才能构造的类型,然后将其用作function_2() 的参数

class created_by_function_1 {
   created_by_function_1() { /* private constructor */ }
   friend created_by_function_1 function_1();
 };
created_by_function_1 function_1() { 
  // do stuff
  return created_by_function_1();
}
void function_2(created_by_function_1) {
} 

现在,如果您第一次调用function_1,则只能使用function_2

auto proof = function_1();
function_2(proof); // OK
function_2(created_by_function_1()); // Compilation error

我建议不要使用这个:)