1. ホーム
  2. c++

[解決済み] C++のオブジェクトからクラス名を取得するには?

2023-06-16 23:37:44

質問

オブジェクト名も取得できますか?

#include<cstdio>

class one {
public:
    int no_of_students;
    one() { no_of_students = 0; }
    void new_admission() { no_of_students++; }
};

int main() {
    one A;
    for(int i = 0; i < 99; i++) {
        A.new_admission();
    }
    cout<<"class"<<[classname]<<" "<<[objectname]<<"has "
        <<A.no_of_students<<" students";
}

のように、名前を取得することができます。

[classname] = A.classname() = one
[objectname] = A.objectname() = A

C++はこれを実現するための機構を提供していますか?

どのように解決するのですか?

プリプロセッサを使用することで、変数名を表示することができます。例えば

#include <iostream>
#define quote(x) #x
class one {};
int main(){
    one A;
    std::cout<<typeid(A).name()<<"\t"<< quote(A) <<"\n";
    return 0;
}

出力

3one    A

を私のマシンで実行します。は # はトークンを文字列に変更しますが、前処理をした後の行は

std::cout<<typeid(A).name()<<"\t"<< "A" <<"\n";

もちろん、次のようなことをすれば

void foo(one B){
    std::cout<<typeid(B).name()<<"\t"<< quote(B) <<"\n";
}
int main(){
    one A;
    foo(A);
    return 0;
}

を取得します。

3one B

というように、コンパイラはすべての変数名を記録しているわけではありません。

gccではtypeid().name()の結果はマングル化されたクラス名であり、そのクラス名を得るために デマングされたバージョン を使用します。

#include <iostream>
#include <cxxabi.h>
#define quote(x) #x
template <typename foo,typename bar> class one{ };
int main(){
    one<int,one<double, int> > A;
    int status;
    char * demangled = abi::__cxa_demangle(typeid(A).name(),0,0,&status);
    std::cout<<demangled<<"\t"<< quote(A) <<"\n";
    free(demangled);
    return 0;
}

で、これは

one<int, one<double, int> > A

他のコンパイラでは、異なる命名規則が使われているかもしれません。