【问题标题】:Which derived class object called the non-virtual function in the base class基类中哪个派生类对象调用了非虚函数
【发布时间】:2019-05-18 23:27:57
【问题描述】:

背景:

我有一个基类 Base,它大部分有“纯”虚函数和一些非虚函数(加上几个虚函数)。 p>

基本上,所有派生类DerivedDerived2等中的通用功能都作为非虚函数存在于基类中。

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

实际上,我想调试一个调用并偶然发现这样一个事实:无论是使用调试器还是使用任何跟踪线,我都无法确定我是从哪个派生类对象中偶然发现这个非虚拟基类函数的.

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

最小工作示例: 这是最小的工作示例。我尽可能地把它拆掉了。

#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;
}

【问题讨论】:

  • 打印这个会告诉你类型。在 Visual Studio 中,对象的类型一目了然,gdb 也是如此。
  • @MatthieuBrucher,:快!确实!没想到!
  • 如果你还没有加入~Base(),那么你应该加入它。如果您有 C++11 或更高版本,还可能值得一看标准 &lt;thread&gt; 库。它与 pthread 非常相似,但具有更好的 (C++) 锁/互斥锁等。
  • 加入Base类析构函数有什么好处呢? (附:我没有 C++11。)
  • 如果基类有虚函数,那么typeid(*this) 将提供最派生类型的type_info 对象。因此,在 gdb 中,您可以使用 printf "%s\n",typeid(*this).__name 或只是 pring typeid(*this) 获取最衍生类型的名称

标签: c++ derived-class base-class


【解决方案1】:

所以为了完整起见,万一其他人(很可能几个月后我自己)再次偶然发现这个问题,这里是我为这个问题实施的一般想法。

#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 中运行时会给出输出:

基地说:4基地
派生说:7派生
其他派生说:12otherDerived

注意:最好创建一个虚函数 name()className() 并在任何地方调用该函数,而不是在代码中到处撒typeid(*this).name()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-16
    • 1970-01-01
    • 1970-01-01
    • 2018-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-11
    相关资源
    最近更新 更多