【问题标题】:Print the class name of derived class using inherited function使用继承函数打印派生类的类名
【发布时间】:2017-10-17 10:33:20
【问题描述】:

有没有什么方法可以打印带有继承函数的派生类的类名,而无需在派生类中重写该函数?

class A {
public:
    virtual void print() { printf("%s", __PRETTY_FUNCTION__); }
};

class B : public A {};

int main() {
    B b;

    b.print() // should yield "B::print()" but yields "A::print()"
}

我要求我可以在一个被覆盖的函数中调用A::print() 来打印与父类相关的属性,但包括当前类名。

【问题讨论】:

  • B类没有print()
  • 如果您想在运行时询问“this 的派生最多的类型是什么”,那么您可以使用typeid(this).name()(仅适用于多态类型)。您可能必须使用特定于编译器的实用程序函数来解密此名称。 Example
  • @cdhowie 我从没想过这可以工作,因为我认为 typeid 运算符在编译时已解决。这就提出了新的问题,typeid 是如何实现的以及类型信息是如何打包到二进制文件中的。
  • @OutOfBound 例如,假设foo 指向多态对象,dynamic_cast<void *>(foo) 将返回指向foo 指向的对象的最派生对象类型的指针.所以通过这种方式,即使没有任何特殊的类型信息,我们也可以在运行时获得指向“真实对象”的指针。从那里,RTTI 系统(typeid() 是其中的一部分)能够为该指针返回一个typeinfo 对象。
  • @OutOfBound 注意dynamic_cast 只是一个例子,表明可以确定最衍生的对象。您实际上不会将 void 指针传递给 typeid(),因为它会告诉您“这是一个 void 指针”。 typeid() 可以在编译时求值,但当操作数是对多态类型的引用时,它在编译时求值。

标签: c++ inheritance


【解决方案1】:

__PRETTY_FUNCTION__ 创建一个编译时确定的字符串。 A 不知道(而且,至关重要的是,不在乎)最终是否有任何东西最终派生出来。它只是创建了一个打印出"virtual void A::print()"的函数。

如果您希望这样的函数能够正确识别调用它的类的名称,一种选择是将名称保持为与基类关联的可查询对象。

class A {
public:
    virtual void print() {printf("(%s) : %s", get_name(), __PRETTY_FUNCTION__);}
    virtual const char * get_name() {return "A";}
};

class B : public A {
public:
    virtual const char * get_name() {return "B";}
};

cmets 中使用typeid 获取动态名称的建议可能也有效,但我之前从未使用过typeid,所以我不能亲自担保它有效性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-08
    • 1970-01-01
    • 2015-11-03
    • 1970-01-01
    • 2012-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多