简体   繁体   English

在编译时确保调用方法

[英]Ensuring a call method at compile time

How can I ensure that a specific method is called, at compile time? 如何确保在编译时调用特定方法?

For example, suppose I have an object with 2 methods: 例如,假设我有一个具有2个方法的对象:

struct Foo
{
   ... func1(...);
   ... func2(...);
};

and I want to ensure that func1 is called before any calls to func2, ie: 并且我想确保在对func2进行任何调用之前先调用func1,即:

int main()
{
   Foo f;
   ...
   f.func1(...);
   f.func2(...);
   f.func2(...); // and so on
}

but I want to generate a compile error if I do something like that: 但是如果我做这样的事情,我想产生一个编译错误:

int main()
{
   Foo f;
   ...
   f.func2(...);  // generate a compile error due the fact that func1 must be called first
   f.func1(...);
   f.func2(...); // and so on
}

While curious why would you do this, general note is that you must expose to user an interface that cannot be used wrong . 尽管好奇为什么要这样做,但一般要注意的是您必须向用户公开一个不能被错误使用的接口 Guts go private: 勇往直前:

struct Foo
{
public:
    void callme()
    {
        func1();
        func2();
    }

private:
    ... func1(...);
    ... func2(...);


};

int main()
{
    Foo f;
    f.callme();
}

If you need to enforce one time initialization of objects, do it in constructor: 如果您需要执行一次对象初始化,请在构造函数中执行:

struct Foo
{
public:
    Foo()
    {
        func1();
    }

    func2(...);
private:
    ... func1(...);
};

int main()
{
    Foo f; // func1() called automagically
    f.func2();
}

Designing class interfaces, you must allways think about the worst things: users never read documentation, users always forget to call foo.initialize() , users always forget freeing memory and it leaks, etc. 在设计类接口时,您必须始终考虑最糟糕的事情:用户从不阅读文档,用户总是忘记调用foo.initialize() ,用户总是忘记释放内存和内存泄漏等。

There is no real way to enforce this at compilation time. 没有真正的方法可以在编译时强制执行此操作。 This is something that the object itself will need to enforce with runtime checks 这是对象本身需要通过运行时检查强制执行的操作

One method that comes to mind, is to let return func1() an object, that acts like a proxy to func2(): 我想到的一种方法是让func1()返回一个对象,该对象的行为类似于func2()的代理:

class Foo {
public:
    Proxy func1();   
private:
    void func2();
    friend class Proxy;
};

class Proxy {
private:
    explicit Proxy(Foo& f) : f_(f) {}
public:
    void func2() {
        f_.func2();
    }
    friend class Foo;
};

Foo f;
f.func1().func2();

An other method (and my favorite) is to let func1() be a constructor or to use an other class, that calls func1() in it's constructor: 另一种方法(也是我最喜欢的方法)是让func1()成为构造函数或使用其他类,该类在其构造函数中调用func1():

class Foo
{
private:
    void func1(), func2();
    friend class FooUser;
};

class FooUser
{
public:
    explicit Proxy(FooUser& f) : f_(f) {
        f.func1();
    }

    void func2() {
        f_.func2();
    }
};

The compiler can't enforce the order of function calls, since in general that can only be determined at run-time. 编译器无法强制执行函数调用的顺序,因为通常只能在运行时确定。 But it can enforce object initialisation before the object can be used. 但是它可以在使用对象之前强制执行对象初始化。 So the best way to get a compile-time check is to do whatever func1 does in a constructor - either part of Foo 's constructor, or a helper object that you need to create in order to call func2 . 因此,获取编译时检查的最好方法是在func1中执行任何操作,该操作是Foo构造函数的一部分,或者是您需要创建以调用func2的帮助对象。

I really do not suggest to do so, but if you need it for debugging purposes you can try following. 我确实不建议这样做,但是如果出于调试目的需要它,可以尝试以下操作。 Change every call func1() to 将每个调用func1()更改为

#define FLAG
func1();

and func2() to 和func2()到

#ifdef FLAG
func2();
#else
#error func1 should be called first!
#endif

So you will receive a compile-time error if func2() will be mentioned upper in text then func1. 因此,如果func2()在文本的上方被提及,然后在func1的上方,您将收到一个编译时错误。 It does not mean it will be really called earlier during execution. 这并不意味着在执行过程中会更早调用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM