使所有 class 方法调用同一个函数

Making all class methods call the same function

所以,我遇到了这种情况:

#include "ActionLog.h"
class Library{
        ActionLog aLog;
        // ... the rest of it is private, mind you :D
    public:
        Library(...);
        void addBook(...);
        void removeBook(...);
        // ... aaand there's a whole bunch of these :)
    };

现在,class ActionLog 有一个 public 方法 void log(...);。一旦实现,它应该记录任何 activity 的开头,作为 class Library 的方法列出(,最终它是 success/failure,这是可选的 ) .

我想知道:有没有更优雅的方法让每个 class Library 的方法调用 aLog.log(...); 方法 when/before 它开始执行?我所说的“优雅”不仅仅是在每个方法中显式调用它...

知道Python version of the solution类似的问题,但我不熟悉Python,所以我什至不确定class 相关原则同样适用。

C++ 没有任何内置的反射方法。无法在运行时或编译时列出方法。你能做的最好的事情就是隐藏登录到一些你将用来定义每个方法的#define,但是预处理器的使用是现代 C++ 中的反模式。

坚持目前的做法。

正如 polkovnikov.ph 所说,如果不进行反思,您将无法使用 python 的方法。

只是为了好玩,我将把它留在这里,但我不推荐使用它:

#include <iostream>    

class Logger
{
    public:
        void log(std::string entry)
        {
            std::cout << entry << std::endl;
        }
};    

class A
{
    Logger mylog;
    public:
        void foo()
        {
            std::cout << "Doing foo" << std::endl;
        }    

        Logger& getLogger()
        {
            return mylog;
        }
};    

#define CALL_FUNC_AND_LOG(obj,func) \
    { obj.getLogger().log("Logging "#func); obj.func(); }    

int main()
{
    A a;
    CALL_FUNC_AND_LOG(a,foo);
    return 0;
}

http://ideone.com/q0VHj6

或自动记录方法范围结束的另一个版本。

#include <iostream>    

class Logger
{
    std::string _entry;
    public:
        Logger(std::string entry)
        {
            _entry = entry;
            std::cout << "Starting execution of " << entry << std::endl;
        }    

        ~Logger()
        {
            std::cout << "Ending execution of " << _entry << std::endl;
        }
};    

class A
{
    public:
        void foo()
        {
            std::cout << "Doing foo" << std::endl;
        }
};    

#define CALL_FUNC_AND_LOG(obj,func) \
    { \
        Logger _mylogger(""#func); \
        obj.func(); \
        \
    }

int main()
{
    A a;
    CALL_FUNC_AND_LOG(a,foo);
    return 0;
}

http://ideone.com/DHf3xu