C++ 如何检查一个函数是否被另一个函数调用?

C++ 如何检查一个函数是否被另一个函数调用?,c++,class,function,C++,Class,Function,我目前正在尝试确保一个类的成员函数只被另一个类的成员函数调用 体系结构是强制的,不能更改,端口意味着在调用b.call()之前,必须在a.call()中执行一些逻辑a.call()因此调用b.call() 我发现我的问题很难回答。只是,问题是我使用的是类,而这两个类的成员函数名相同,因此#define尝试替换所有具有不同原型的实例。能否更改b.call以引用a?这样,b.call可以调用a.call本身: struct A { void call() { // do st

我目前正在尝试确保一个类的成员函数只被另一个类的成员函数调用

体系结构是强制的,不能更改,端口意味着在调用
b.call()
之前,必须在
a.call()
中执行一些逻辑
a.call()
因此调用
b.call()


我发现我的问题很难回答。只是,问题是我使用的是类,而这两个类的成员函数名相同,因此
#define
尝试替换所有具有不同原型的实例。

能否更改
b.call
以引用
a
?这样,
b.call
可以调用
a.call
本身:

struct A {
    void call() {
        // do stuff
    }
};

struct B {
    void call(A & a) {
        a.call();
        // do stuff
    }
};

这确保在执行其余的
b.call
之前始终调用
a.call

使用标志如何

a.call()
{
    // ...
    flag = 1;
    b.call();
    flag = 0;
}

b.call()
{
    if (flag == 0)
        return;

    // ...
}

我向你推荐最新的。这对于细粒度地控制谁可以用你的函数做什么非常有用。

在我看来,选项是:

  • 使
    b.呼叫
    private并使
    b
    添加
    a
    a.呼叫
    作为
    朋友
  • b.call
    转换为一个类,并将主体放入具有
    a
    a.call
    作为
    朋友的私有构造函数中
  • grep
    b.call
    的源代码,确保唯一的调用在
    a.call
    中,并在声明中添加注释,说明“如果调用此函数,您将被解雇”
  • 更改
    b.call
    以获取至少一个它需要的值作为参数(即使它忽略它并使用其他地方的值)

如果您为特定平台(如x86或x64)编程,并且您知道调用约定(如cdecl),那么您可以

假设您想检查调用函数的对象,那么在调用成员函数之前使用推送到堆栈的
this
指针:获取
this
指针,并将其与您想要的对象进行比较(
this_指针==a

如果要检查某个函数,请从堆栈中获取调用方地址并对照该函数进行检查:
caller\u address==A::call
。如果它是一个虚拟函数,请使用
this
指针获取
vtable


根据调用约定和在堆栈上推送变量的顺序,您可能必须首先检查输入变量的大小,以便获得所需的信息。

是的,第一个选项就是我最后所做的。我会删除我的答案并接受你的。@3nixios:不过请注意,现在
a
中的每个函数都可以调用
b.call()
@Xeo我同意这可能会有问题,但错误调用
b.call
的余地要小得多,尽管我的问题很具体,但这对我来说应该足够好了。谢谢。+1是的,保留依赖关系会很好,但我更喜欢使用friend类“cleaner”。@3nixios:它们更干净,但按照您陈述问题的方式,它们并不能完全解决问题。朋友的任何方法都可以调用该方法,因此您仍有可能以错误的顺序调用。@Space\u C0wb0y这是真的,但对于我的特定用途,这目前已经足够了。你的答案更能被全世界接受,这就是为什么我仍然投了赞成票。这需要两个类之间有一个共享的标志,我觉得这不太符合我的口味。另外,friend类提供的编译时检查更合适。这真的很酷。我不会想到的。@Xeo:哦,这是个好名字,我们在一年前奋斗过,没有人知道它的名字,我喜欢你的:)@Space:我喜欢这种模式(特别是C++0x版本),我会尽可能地传播它。:)@Matthieu:如果你看了这个问题的OP的问题,应该有一个问名字(或者一个相关的问题有名字),这是公认的答案编辑:。@Xeo:是的,但是放弃朋友是一个不错的举动:)我提到的斗争正是你链接的问题:)