从父类访问派生类名

时间:2014-02-03 09:57:53

标签: c++ visibility

在我正在工作的项目中,我需要能够访问程序中每个实例的完整类名。我的方法是声明一个基类,所有类都将从该基类派生,并且该方法将返回一个方法,该方法将返回给定实例的类的名称,并正确地进行解码。这看起来如下:

class Base { 
  public: 
  std::string *getClassName() { 
    char *str = (char*) malloc(1024);
    size_t size = 1024;
    int status;
    char *res = abi::__cxa_demangle( typeid(*this).name(), str, &size, &status );
    return new std::string(res);
  };

 class A : public Base { /*...*/ };
 class B : public A { /*...*/ };
 // ... and so on

问题在于,当我从B类实例访问getClassName时,它不返回Base::A::B而只返回Base,这是从{声明getClassName的地方。

我找到的唯一解决方案是使getClassName虚拟并强制每个类实现它。但这意味着重写总是相同的代码,这是我不想要的。你知道任何优雅的解决方案吗?

3 个答案:

答案 0 :(得分:4)

您只需在Base类中定义虚拟析构函数:

#include <iostream>
#include <malloc.h>
#include <cxxabi.h>

using namespace std;

class Base {
public:
    virtual ~Base() {}
    std::string getClassName() {
        char *str = (char*) malloc(1024);
        size_t size = 1024;
        int status;
        char *res = abi::__cxa_demangle( typeid(*this).name(), str, &size, &status );
        return std::string(res);
    }
};

class A : public Base { /*...*/ };
class B : public A { /*...*/ };

int main()
{
    A a;
    B b;


    cout << a.getClassName() << endl;
    cout << b.getClassName() << endl;
}

输出:

./test
A
B
在这种情况下BTW最好让__cxa_demangle分配内存(不要忘记:: free()它因为这个示例代码有内存泄漏)

答案 1 :(得分:0)

使您的Base类成为派生类的模板,并将派生类的this指针传递给构造函数。类似的东西:

template <DerivedT> class Base {
    DerivedT * self;
  public:
    Base(DerivedT * s) : self(s) {}
  // ....
};

然后在typeid而不是*self上致电*this

您的派生类必须成为:

template <DerivedT> class A : public Base<DerivedT> { /*...*/ };
class B : public A<B> { /*...*/ };

沿着构造函数链向上传递this

答案 2 :(得分:0)

有一个在Class Base中受保护的变量,并在每个派生类中设置它的值,并在getClassName中返回相同的变量..

class Base{
protected:
std:string* _pstrClassName;
}

class A{
 A():_pstrClassName("A"){

 }
}