如何在编译时确保调用特定方法?
例如,假设我有一个包含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
}
答案 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,则会收到编译时错误。这并不意味着它在执行期间会被更早地调用。