如何检查一个函数是不是被另一个函数调用?

Posted

技术标签:

【中文标题】如何检查一个函数是不是被另一个函数调用?【英文标题】:How can I check a function was called by another function?如何检查一个函数是否被另一个函数调用? 【发布时间】:2011-07-01 08:32:49 【问题描述】:

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

架构是强加的,无法更改,端口意味着在调用b.call()之前必须在a.call()中完成一些逻辑。 a.call() 因此调用 b.call() 来简化事情并确保遵守顺序。

我在我的问题中找到了this answer。只是,问题是我正在使用类,并且这两个类具有 same 成员函数名称,因此 #define 尝试替换所有具有不同原型的事件。

【问题讨论】:

【参考方案1】:

我推荐passkey pattern。它非常适合对谁可以对您的函数执行什么操作进行细粒度控制。

【讨论】:

这真的很酷。我不会想到的。 @Xeo:哦,这是个好名字,一年前我们挣扎过,没人知道它的名字,我喜欢你的 :) @Space:我喜欢这种模式(尤其是 C++0x 版本),我会尽可能地传播信息。 :) @Matthieu:如果您查看该问题的 OP 问题,则应该有一个要求名称(或相关问题之一),这是公认的答案。 :) 编辑:Here it is. @Xeo:是的,但是放弃朋友是一个不错的举动:)我提到的斗争是你链接的确切问题:)【参考方案2】:

在我的脑海中,选项将是:

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

【讨论】:

是的,第一个选项是我最后所做的。我会删除我的答案并接受你的。 @3nixios:请注意,现在a 中的每个 函数都可以调用b.call() @Xeo 我同意这可能是有问题的,但它留下的错误调用b.call 的空间要小得多,虽然我的问题很具体,但这对我来说应该足够好了。谢谢。【参考方案3】:

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

struct A 
    void call() 
        // do stuff
    
;

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

这确保a.call 总是在b.call 的其余部分被执行之前被调用。

【讨论】:

+1 是的,保持依赖关系会很好,但我更喜欢使用 friend 类'cleaner'。 @3nixios:它们更干净,但是你陈述问题的方式,它们并没有完全解决它。朋友的任何方法都可以调用该方法,所以还是有调用顺序错误的可能。 @Space_C0wb0y 这是真的,但对于我的具体用途来说,目前这已经足够了。您的回答在全球范围内更容易接受,这就是我仍然投赞成票的原因。【参考方案4】:

使用标志怎么样?

a.call()

    // ...
    flag = 1;
    b.call();
    flag = 0;


b.call()

    if (flag == 0)
        return;

    // ...

【讨论】:

这需要在两个类之间共享一个标志,我觉得 vto 不太合我的口味。友元类提供的编译时检查也更合适。【参考方案5】:

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

假设您要检查调用该函数的 对象,因此使用在调用成员函数之前压入堆栈的 this 指针:获取 this 指针并进行比较它与你想要的对象 (this_pointer == a)

如果您想检查某个函数,请从堆栈中获取调用者地址并检查该函数:caller_address == A::call。如果是虚函数,使用this指针获取vtable

根据调用约定和将变量压入堆栈的顺序,您可能必须首先检查输入变量的大小,才能获得所需的信息。

【讨论】:

以上是关于如何检查一个函数是不是被另一个函数调用?的主要内容,如果未能解决你的问题,请参考以下文章

在另一个计算属性上调用 getter 不是测试中的函数

如何在编译时检查是不是存在可以使用特定参数集调用的函数?

如何检查检查PInvoke签名的调用约定和参数与非托管的目标签名是不是匹配?

Unity 单元测试 - 检查带有参数的函数调用是不是引发异常

线程学习笔记

开玩笑检查是不是调用了函数[重复]