C++ 从父类访问派生类名

C++ 从父类访问派生类名,c++,visibility,C++,Visibility,在我工作的项目中,我需要能够访问程序中每个实例的完整类名。我的方法是声明一个基类,所有类都将从该基类派生,该基类将有一个方法,该方法将正确地请求返回给定实例的类的名称。这将如下所示: class Base { public: std::string *getClassName() { char *str = (char*) malloc(1024); size_t size = 1024; int status; char *res = abi::_

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

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
虚拟化,并强制每个类实现它。但这意味着总是重写相同的代码,这是我不想要的。您知道有什么解决方案吗?

您可以在基类中定义虚拟析构函数:

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

顺便说一句,在这种情况下,最好让&uuuucxa\udemangle分配内存(不要忘记::free()它,因为这个示例代码有内存泄漏)

在派生类上创建
类a模板,并将派生类的
这个
指针传递给构造函数。比如:

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

然后沿着构造函数链向上传递
这个

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

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

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

 }
} 

[OT]:签名应该是
std::string getClassName()const
。您可以使用
char str[1024]
来避免memleak。
template <DerivedT> class A : public Base<DerivedT> { /*...*/ };
class B : public A<B> { /*...*/ };
class Base{
protected:
std:string* _pstrClassName;
}

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

 }
}