有一个布尔变量来确定是否A已被调用。然后,当有人试图在B没有设置这个布尔变量的情况下调用时,抛出一个 IllegalStateException。
或者您可以B简单地调用,A因为它似乎无法在不A首先被调用的情况下执行。
否则,由于这两种方法都是公开的,因此真的没有其他方法可以强制执行此操作。
使用布尔值是一个良好的开端,抛出访问可以正常工作.
但是,有时能够在编译时强制执行此功能.在这种情况下,你唯一真正的选择是使用一些技巧.
只在您的类中公开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.
}
Run Code Online (Sandbox Code Playgroud)
您还可以使用实现(或提供虚拟)B()的基类的受保护继承来实现类似的功能.
一种方法是重新设计你的课程有点不同.考虑一个简单的数据库类,需要在使用之前进行初始化.我是一个Java人,所以......
public class Database {
public void init(String username, String password) // must call this first!
public List<Object> runQuery(String sql) // ...
}
Run Code Online (Sandbox Code Playgroud)
所以我需要先调用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) // ...
}
}
Run Code Online (Sandbox Code Playgroud)
所以现在我必须通过工厂来获取底层对象.
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");
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1689 次 |
| 最近记录: |