防止在另一个方法之前调用方法

时间:2012-08-26 02:08:57

标签: java c++ methods call

这个问题有点宽泛和概念性。

我有一个有各种方法的课。我们称他们为AB。我怎样才能确保将来使用此类的其他开发人员在首次调用方法A之前不会调用方法B?

我在C ++中这样做,但一般来说,执行此操作的最佳方法是什么?我有一些天真的想法,比如使用布尔变量,但我也希望听到其他一些想法。

6 个答案:

答案 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”。