这个问题有点宽泛和概念性。
我有一个有各种方法的课。我们称他们为A
和B
。我怎样才能确保将来使用此类的其他开发人员在首次调用方法A之前不会调用方法B?
我在C ++中这样做,但一般来说,执行此操作的最佳方法是什么?我有一些天真的想法,比如使用布尔变量,但我也希望听到其他一些想法。
答案 0 :(得分:10)
保证这一点的一种方法?让方法B负责调用方法A一次。
其他任何东西都是脆弱的API。
答案 1 :(得分:5)
使用布尔值是一个很好的开始,抛出访问可以正常工作。
然而,有时能够在编译时强制执行此功能。在这种情况下,你唯一真正的选择是使用一些技巧。
只在您的类中公开A,使其返回包含B的代理。
class MyClass {
public:
struct BProxy {
public:
MyClass * root;
void B() { root->B(); }
protected:
BProxy( MyClass * self ) : root(self) {}; // Disable construction
friend class MyClass; //So that MyClass can construct it
};
BProxy A() { ... return BProxy(this); }
friend class BProxy; // So that BProxy can call B()
protected
void B() { ... }
};
int main() {
MyClass m;
BProxy bp = m.A();
// m.B(); can't do this as it's private - will fail at compile time.
bp.B(); // Can do this as we've got the proxy from our previous call to A.
}
您还可以使用受保护的继承从实现(或提供虚拟)B()的基类中实现类似的东西。
答案 2 :(得分:5)
一种方法是以不同的方式重新设计你的课程。考虑一个简单的数据库类,需要在使用之前进行初始化。我是一个Java人,所以......
public class Database {
public void init(String username, String password) // must call this first!
public List<Object> runQuery(String sql) // ...
}
所以我需要先调用init。我可以创建一个DatabaseFactory来执行初始化并返回实际的数据库对象。我们可以隐藏构造函数,这样只有DatabaseFactory才能创建数据库(在Java中是一个嵌套类,在C ++中可能是朋友类?)。
public class DatabaseFactory {
public Database init(String username, String password) // ...
public class Database {
private Database() {}
public List<Object> runQuery(String sql) // ...
}
}
所以现在我必须经过工厂才能找到基础对象。
DatabaseFactory factory = new DatabaseFactory();
Database database = factory.init("username", "password"); // first init (call method A)
// now I can use database (or B in your case)
database.runQuery("select * from table");
答案 3 :(得分:4)
有一个布尔变量,用于确定是否已调用A
。然后,当有人试图在没有设置此布尔变量的情况下调用B
时,抛出IllegalStateException。
或者你可以让B
简单地调用A
,因为它似乎无法在没有首先调用A
的情况下执行。
否则,由于这两种方法都是公开的,因此实际上没有其他方法可以强制执行此操作。
答案 4 :(得分:2)
保证它的一种方法是A
在类的构造函数中完成。如果构造函数失败(抛出),那么其他开发人员就没有任何错误B
的错误。{1}}。如果构造函数成功,则A
至少完成一次,因此B
是有效的操作。
答案 5 :(得分:2)
我会使方法“A”构造函数初始化对象。这必须调用一次使用由编译器强制执行的对象。之后,您可以在必须调用构造函数的情况下调用方法“B”。