如何只允许在调用函数 B 后调用函数 A?

How can I only allow a function A to be called only after function B is called?

本文关键字:调用 函数      更新时间:2023-10-16

请考虑以下代码类:

class A {
public:
int number;
vector<int> powers;
A () {
number = 5;
powers.resize(100);
}
long long getPower(int x) {
return powers[x];
}
void precompute() {
powers[0] = 1;
for (int i = 1; i < 100; i++) {
powers[i] = powers[i - 1] * number;
}
}
};

在类A中,我们有一个名为powers的向量和一个整数number,其属性powers[k]存储调用precompute()函数后的数量numbers^k。如果我们想回答"为某个整数0 <= x < 100计算numbers^x"形式的几个查询,那么预先计算所有这些幂并在需要它们时将它们作为常量时间操作返回是有意义的(注意:这不是我实际面临的问题。为了一个例子,我编造了这个问题。请忽略numbers^x将超过long long的最大值的事实(。

但是,存在一个问题:用户必须先调用precompute()函数,然后才能调用getPower()函数。

这让我想到了以下问题:是否有一些好方法可以强制执行某些函数A只能在调用函数B后调用的约束?当然,可以只使用flag变量,但我想知道是否有更优雅的方法可以做到这一点,以便它成为编译时错误。

另一种选择是始终在构造函数中调用precompute()函数,但如果一开始我们并不总是调用precompute(),这可能不是最佳解决方案。如果调用precompute()的成本足够高(计算(,则此方法将不可取。

我宁愿得到编译时错误而不是运行时错误,但我对所有方法都持开放态度。有人有什么想法吗?

您的问题的一种解决方案是在class A的构造函数中调用precompute函数。

或者,正如注释部分中已经建议的那样,您可以使函数getPower检查一个标志,该标志指定是否已调用precompute,如果没有,则执行调用本身或打印错误消息。

我想不出一种强制在编译时完成此检查的方法。但是,如果要从发布版本中消除此运行时检查,则可以使用条件编译,以便这些检查仅包含在调试版本中,例如通过使用assert宏或使用预处理器指令,如下所示:

// note that NDEBUG is normally only defined in release builds, not debug builds
#ifdef NDEBUG
//check for flag here and print error message if flag has unexpected value
#endif

作为替代方法,若要强制实施计时依赖关系,可以将依赖关系显式化。

例如:

class PowerGetter
{
friend class A;
const A& a;
public:
long long getPower(int x) {
return a.powers[x];
}
};
class A {
public:
int number = 5;
std::vector<int> powers = std::vector<int>(100);
A() = default;
PowerGetter precompute() {
powers[0] = 1;
for (int i = 1; i < 100; i++) {
powers[i] = powers[i - 1] * number;
}
return {*this};
}
};

然后要调用getPower我们需要一个只能通过先调用precompute来获得的PowerGetter

对于这个人为的例子,更简单的是将初始化放在A中。