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

C++ c++;如何定义需要为其他开发人员调用的常量函数顺序,c++,function,C++,Function,我遇到的问题是,我有几个函数需要按定义的顺序调用——顺序不能是可破坏的。 现在代码需要在我完成代码后继续开发。 我在寻找一些方法来设置某种不可破坏的结构中的函数。 例如,我有: function_1() { //do some stuff ..} ; // must be first function_2() { //do some stuff based on function_1()..}; // must be second function_3() { //do some st

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

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()app函数下。

您可以创建包装函数

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

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

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

现在,如果您第一次调用
function\u 1
,则只能使用
function\u 2

auto proof = function_1();
function_2(proof); // OK

function_2(created_by_function_1()); // Compilation error

我建议不要使用此选项:)

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

在你的头上放

 bool function_4();
在相应的转换单元中,创建一个未命名的名称空间,以防止其他人看到这些函数

 namespace {
     bool function_1() {
     }
     bool function_2() {
     }
     bool function_3() {
     }
 }
并定义
函数_4

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

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

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.
}

我想你有充分的理由不把这三个函数都打包成一个函数

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

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; 
    ...
}
static int function\u status=0;//共享状态:未调用任何内容
函数_1(){
如果(状态>0)
抛出异常(“函数_1必须首先调用,并且只能调用一次”);
status=1;//调用了函数_1
...
}   
函数_2(){
if(status2)//我想可以多次调用函数2
抛出异常(“3之后不能调用函数_2”);
状态=2;
...
}
函数_3(){

if(status)为什么不简单地提供一个可以通过API调用的第四个函数,并将另外三个函数移动到一个未命名的名称空间中呢?例如,Make
function123(){function1();function2();function3();}
?这就是所谓的模板模式。看看你的声誉,我想如果你问这个问题,那是因为有一个合理的理由不把这三者都放在一个包装中,不是吗?加上1因为这不值得投反对票。匿名投票人又一次逍遥法外了。这个例子显示了预先确定fu顺序的糟糕方法编译器优化可以改变顺序,甚至可以跳过这些逻辑函数中的相同函数expressions@VolAnd编译器绝对不会更改此逻辑函数的顺序。标准规定必须按此顺序调用这些函数。如果编译器跳过任何函数,则如果前一个函数失败,则将是后一个函数ed,这是“短路行为”,这正是OP想要的。@Cyber抱歉,我不得不在回答时采用你的解决方案。我一直忽略了“短路行为”从OP的问题中指出。当然你是对的。@Cyber:请解释一下,为什么你如此确信任何在表达式
func_1()&&func_2()&&func_1()&&func_3()
中具有任何优化级别的编译器都会调用
func_1()
两次?如果你再往前走一步,你会得到一个流畅的api风格“myContext.function1().function2().function3()”@tofi9我想OP希望在调用他的函数之间有其他东西,否则为什么要单独公开它们(这就是为什么我认为他没有使用模板方法模式的原因)这里有一个陷阱:没有任何东西强迫客户机代码调用所有函数
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; 
    ...
}