代码之家  ›  专栏  ›  技术社区  ›  Duck Dodgers

哪个派生类对象调用基类中的非虚函数

  •  0
  • Duck Dodgers  · 技术社区  · 6 年前

    背景:

    我有一个基类, 底座 ,其中 主要地 “纯”虚拟函数和一些非虚拟函数(加上几个虚拟函数)。

    基本上,所有派生类中的公共功能 派生的 , 嘲笑2 等等,作为非虚函数存在于基类中。

    问题: 如果任何派生类中的一个对象调用基类中的任何非虚拟函数,则如何(如果有)知道哪个派生类对象调用了此非虚拟基类函数。

    实际上,我想调试一个调用,但无意中发现,无论是使用调试器还是使用任何traceline,我都无法确定是从哪个派生类对象偶然进入这个非虚拟基类函数。

    想想看,在我写这个问题的时候,我能想到的一个方法是,我可以在每个派生类中有一个静态成员字符串变量,并将它作为参数传递给非虚拟基类函数。但是,这是唯一的办法吗?

    最小工作示例: 下面是最基本的工作示例。我尽量把它脱下来。

    #include <iostream>
    
    
    #include <pthread.h>
    #include <string>
    #include <errno.h>
    #include <cstring>
    
    class Base {
    public:
        Base() {}
        virtual ~Base() {}
        int waitForThreadToExit() {
            int error = pthread_join(m_Thread, NULL);
            if (0 != error) {
                std::cerr << "Error from pthread_join(). errorCode:" << strerror(errno) << std::endl;
            }
            return error;
        }
    
        int start() {
            if ((startThread()) != 0) {
                 std::cerr << "error returned from the start() function." << std::endl;
             }
        }
    
    protected:
        virtual int runThread(void) {
          std::cout << "Reimplement" << std::endl;;
          return -1;
        }
        int startThread() {
            int error = pthread_create(&m_Thread, NULL, internalThreadEntryFunc, this);
            return error;
        }
    
    private:
        static void* internalThreadEntryFunc(void* This) {
            ((Base *) This)->runThread();
            return NULL;
        }
        pthread_t m_Thread;
    };
    
    
    class Derived: public Base {
    public:
        Derived() {}
        virtual ~Derived() {}
    
    private:
        virtual int runThread(void) {
            while(1) {
                 std::cout << "Sehr gut!" << std::endl;;
                 return 0;
            }
        }
    
    };
    
    class Derived2: public Base {
    public:
        Derived2() {}
        virtual ~Derived2() {}
    
    private:
        virtual int runThread(void) {
            while (1)
            {
                std::cout << "Sehr sehr gut!" << std::endl;;
                return 0;
            }
        }
    
    };
    
    
    int main()
    {
        std::cout << "Hello World!" << std::endl;
        Derived d;
        Derived2 d2;
        d.start();
        d2.start();
        d.waitForThreadToExit();
        d2.waitForThreadToExit();
        return 0;
    }
    
    0 回复  |  直到 6 年前
        1
  •  0
  •   Duck Dodgers    5 年前

    所以为了完整起见,如果其他人(很可能几个月后我自己)再次遇到这个问题,这里是我为这个问题实现的一般思想。

    #include <iostream>
    #include <typeinfo>
    
    class base {
    public:
        virtual const char* name() {
            return typeid(*this).name();
        }
        virtual ~base(){}
    };
    
    class derived : public base {};
    class otherDerived : public base {};
    
    int main () {
        base b;
        derived d;
        otherDerived d2;
    
        std::cout << "base says:" << b.name() << std::endl;
        std::cout << "derived says:" << d.name() << std::endl;
        std::cout << "other derived says:" << d2.name() << std::endl;
    }
    

    它在我的QtCreator中运行时给出输出:

    基地说:4base
    派生说:7dervied
    其他派生说:12其他派生

    注: 最好做一个虚拟函数 name() className() 在任何地方都调用这个函数,而不是喷洒 typeid(*this).name() 密码里的每一处。