You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中如何在父类方法内获取调用该方法的子类名称

在C++父类方法中获取调用它的子类类名

方法1:虚函数实现多态返回类名

这是最实用的方案,借助C++多态特性实现。在父类里定义一个纯虚函数用来返回类名,每个子类重写这个函数,返回自己的类名称。父类方法调用这个虚函数时,会自动触发子类的实现,拿到真实的子类类名。

代码示例:

#include <iostream>
#include <string>

class Base {
public:
    virtual ~Base() = default;
    // 纯虚函数,子类必须重写
    virtual std::string getClassName() const = 0;
    
    void printClassName() {
        // 调用子类的getClassName
        std::cout << "当前子类类名:" << getClassName() << std::endl;
    }
};

class Derived1 : public Base {
public:
    std::string getClassName() const override {
        return "Derived1";
    }
};

class Derived2 : public Base {
public:
    std::string getClassName() const override {
        return "Derived2";
    }
};

int main() {
    Base* d1 = new Derived1();
    d1->printClassName(); // 输出:当前子类类名:Derived1
    
    Base* d2 = new Derived2();
    d2->printClassName(); // 输出:当前子类类名:Derived2
    
    delete d1;
    delete d2;
    return 0;
}

方法2:用RTTI(运行时类型信息)

C++的RTTI机制可以通过typeid获取对象的实际类型,但有两个前提:

  • 编译时要开启RTTI支持(主流编译器默认开启,比如GCC加-frtti,MSVC默认就有)
  • 父类必须至少有一个虚函数(否则typeid只会识别父类类型,触发不了多态)

代码示例:

#include <iostream>
#include <typeinfo>
#include <string>

class Base {
public:
    virtual ~Base() = default; // 必须有虚函数才能让typeid识别子类类型
    
    void printClassName() {
        // typeid(*this).name()返回的格式随编译器变化,比如GCC会带长度前缀
        std::cout << "当前子类类名:" << typeid(*this).name() << std::endl;
    }
};

class Derived : public Base {};

int main() {
    Base* d = new Derived();
    d->printClassName(); // GCC下可能输出"6Derived",MSVC下输出"Derived"
    
    delete d;
    return 0;
}

注意:typeid返回的名称格式不统一,如果需要标准化的类名,建议结合方法1来处理。

方法3:宏定义减少重复代码

如果有大量子类,不想每个都手动写重写函数,可以用宏自动生成返回类名的代码:

#include <iostream>
#include <string>

class Base {
public:
    virtual ~Base() = default;
    virtual std::string getClassName() const = 0;
    
    void printClassName() {
        std::cout << "当前子类类名:" << getClassName() << std::endl;
    }
};

// 定义宏,自动生成getClassName的重写函数
#define DEFINE_CLASS_NAME(className) \
    std::string getClassName() const override { \
        return #className; \
    }

class DerivedA : public Base {
public:
    DEFINE_CLASS_NAME(DerivedA)
};

class DerivedB : public Base {
public:
    DEFINE_CLASS_NAME(DerivedB)
};

int main() {
    Base* a = new DerivedA();
    a->printClassName(); // 输出:当前子类类名:DerivedA
    
    Base* b = new DerivedB();
    b->printClassName(); // 输出:当前子类类名:DerivedB
    
    delete a;
    delete b;
    return 0;
}

内容的提问来源于stack exchange,提问作者Yasasa Jayasuriya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 16:15:42