在编译时确保调用方法

时间:2014-02-17 17:30:28

标签: c++ c++11

如何在编译时确保调用特定方法?

例如,假设我有一个包含2个方法的对象:

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

我希望确保在调用func2之前调用func1,即:

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

但是如果我这样做的话,我想生成一个编译错误:

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
}

5 个答案:

答案 0 :(得分:11)

虽然好奇为什么要这样做,但一般要注意的是,你必须 向用户公开一个不能错误使用的界面 。胆量私有化:

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

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


};

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

如果需要强制执行一次对象初始化,请在构造函数中执行:

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

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

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

设计类接口时,你必须始终考虑最糟糕的事情:用户永远不会阅读文档,用户总是忘记调用foo.initialize(),用户总是忘记释放内存并且泄漏等等。

答案 1 :(得分:5)

在编译时没有真正的方法来强制执行此操作。这是对象本身需要通过运行时检查强制执行的东西

答案 2 :(得分:3)

我想到的一个方法是让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();

另一个方法(和我最喜欢的)是让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();
    }
};

答案 3 :(得分:1)

编译器无法强制执行函数调用的顺序,因为通常只能在运行时确定。但它可以在使用对象之前强制执行对象初始化。因此,获得编译时检查的最佳方法是在构造函数中执行func1所做的任何操作 - Foo的构造函数的一部分,或者为了调用而需要创建的辅助对象func2

答案 4 :(得分:1)

我真的不建议这样做,但如果你需要它用于调试目的,你可以尝试以下。 将每个调用func1()更改为

#define FLAG
func1();

和func2()到

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

因此,如果func2()将在文本中提到func1,则会收到编译时错误。这并不意味着它在执行期间会被更早地调用。