一个类能否在内部监控其成员函数的使用和参数

Posted

技术标签:

【中文标题】一个类能否在内部监控其成员函数的使用和参数【英文标题】:Can a class internally monitor its member function usage and arguments 【发布时间】:2021-08-03 14:00:59 【问题描述】:

一个类是否可以在不修改成员函数的情况下监视其成员函数何时被调用以及向函数提供的参数?我定义了一个类,我希望可以选择在不修改函数本身的情况下切换此类功能。在对象生命周期结束时,我想将此信息输出到某处的日志文件中。

【问题讨论】:

你当然可以将它包装在另一个类中,该类将在提供与原始类相同的接口的同时进行监控。 我认为你唯一的选择是proxy他们。您不会直接修改您的 memebr 函数,但您必须编写一些代码。 监控使用情况是什么意思?修改函数的源代码是完全禁止的吗? @S.Ptr 我想知道哪个成员函数被它的名字调用。修改源代码并非没有限制,但我想先探索其他选项。 由于这样的日志记录可能会对性能产生很大影响并创建大型日志文件,当遵循编写短函数的建议时,我认为最好只对某些函数进行显式日志记录(可能使用宏和可变参数模板) 【参考方案1】:

如果您无法更改原始类,则可以编写一个适配器来为您进行日志记录。

例子:

#include <iostream>
#include <map>

class ProfilingSummary

public:
    static ProfilingSummary& Instance()
    
        static ProfilingSummary myInstance;
        return myInstance;
    

    void Log(const std::string& method)
    
        auto result_pair = Results.insert(std::make_pair(method, 1));
        if(!result_pair.second)
        
            // method already inserted
            auto& count = result_pair.first->second;
            count++;
        
    

    ProfilingSummary(ProfilingSummary const&) = delete;             // Copy construct
    ProfilingSummary(ProfilingSummary&&) = delete;                  // Move construct
    ProfilingSummary& operator=(ProfilingSummary const&) = delete;  // Copy assign
    ProfilingSummary& operator=(ProfilingSummary&&) = delete;       // Move assign

private:
    ProfilingSummary() = default;
    
    ~ProfilingSummary()
    
        std::cout << std::endl;
        std::cout << "Profiling Summary: " << std::endl;
        for(const auto& result : Results)
        
            const auto method = result.first;
            const auto count = result.second;
            std::cout << method << 
                " called " << count << std::endl;
        
    

    std::map<std::string, int> Results;
;

struct Original

    void Foo()  std::cout << "Hello World" << std::endl; 
;

struct OriginalAdapter

    void Foo() 
    
        ProfilingSummary::Instance().Log(__FUNCTION__); // use symbol for function name, you can copy this for each method
        _Original.Foo();
    

private:
    Original _Original;
;

int main()

    OriginalAdapter original;
    original.Foo();

输出:

Hello World

Profiling Summary: 
Foo called 1

【讨论】:

提及这种方法的局限性可能很有用。这些类型完全不相关(没有共享基类),因此您需要使用Original 更新大量代码,并且使用模板可能会有更多差异。

以上是关于一个类能否在内部监控其成员函数的使用和参数的主要内容,如果未能解决你的问题,请参考以下文章

C++ - 在内部,当定义一个类的成员函数时,应该使用成员变量名称还是它的 getter 函数?

如何在内部函数中使用类变量?

继承 Java 私有成员

类_类的定义

成员函数的重载,覆盖与隐藏

零值初始化&字符串常数作为函数模板参数