gpt4 book ai didi

c++ - 在 C++11 中检查对象类型

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:07:48 24 4
gpt4 key购买 nike

我有继承自 A 的类 B。

class A
{
};

class B : public A
{
};

我有三个对象。

A* a = new A();
A* a2 = new B();
B* b = new B();

我想检查 a 是 A 类型的对象,a2 是 B 类型的对象(不是 A),b 是 B 类型的对象。

我试过输入比较,但没有给出正确答案。

cout << (typeid(*a) == typeid(A)) << endl; // -> 1
cout << (typeid(*a2) == typeid(A)) << endl; // -> 1
cout << (typeid(*b) == typeid(A)) << endl; // -> 0

cout << (typeid(*a) == typeid(B)) << endl; // -> 0
cout << (typeid(*a2) == typeid(B)) << endl; // -> 0
cout << (typeid(*b) == typeid(B)) << endl; // -> 1

我尝试了动态转换,但出现了编译错误。

B* derived = dynamic_cast<B*>(a);
if (derived) {
cout << "a is B";
}
derived = dynamic_cast<B*>(a2);
if (derived) {
cout << "a2 is B";
}
derived = dynamic_cast<B*>(b);
if (derived) {
cout << "b is B";
}

typename.cpp: In function 'int main(int, char**)':
typename.cpp:27:36: error: cannot dynamic_cast 'a' (of type 'class A*') to type 'class B*' (source type is not polymorphic)
B* derived = dynamic_cast<B*>(a);
^
typename.cpp:31:34: error: cannot dynamic_cast 'a2' (of type 'class A*') to type 'class B*' (source type is not polymorphic)
derived = dynamic_cast<B*>(a2);

我使用了静态转换,但我得到了错误的答案。

B* derived = static_cast<B*>(a);
if (derived) {
cout << "a is B"; // -> YES
}
derived = static_cast<B*>(a2);
if (derived) {
cout << "a2 is B"; // -> YES
}
derived = dynamic_cast<B*>(b);
if (derived) {
cout << "b is B"; // -> YES
}

如何正确识别 C++11 中的对象类型?

最佳答案

一些类是多态的,一些是非多态的。

一个多态类有一个或多个虚函数(可能是继承的),一个非多态类有零个虚函数。

你的 A 和 B 是非多态的。

A 和 B 的多态版本将表现出您想要的行为:

#include <iostream>
#include <typeinfo>

using namespace std;

struct A
{
virtual ~A() {}; // add virtual function
};

class B : public A
{
};

A* a = new A();
A* a2 = new B();
B* b = new B();

int main()
{
cout << (typeid(*a) == typeid(A)) << endl; // -> 1
cout << (typeid(*a2) == typeid(A)) << endl; // -> 0 <-- CHANGED
cout << (typeid(*b) == typeid(A)) << endl; // -> 0

cout << (typeid(*a) == typeid(B)) << endl; // -> 0
cout << (typeid(*a2) == typeid(B)) << endl; // -> 1 <-- CHANGED
cout << (typeid(*b) == typeid(B)) << endl; // -> 1
}

多态类的实例在运行时存储其最派生对象的动态类型。

(在您的示例中,a2 是指向 A 的指针类型,并且指向 A 类型的对象,但是该对象只是一个基类子对象类型 B 的最派生对象的。你想要得到的是查询 a2 时这个最派生对象 B 的类型。为此你需要一个多态类。)

这就是多态类如何支持最派生对象的 dynamic_casttypeid(以及虚函数分派(dispatch))。

非多态类没有这些信息,因此它们只能报告编译时已知的静态类型。非多态类比多态类更紧凑和高效。这就是为什么并非所有 C++ 类都是多态的。该语言让程序员选择性能和功能之间的权衡。例如:

struct X { int x; };
struct Y : X {};
struct Z : Y {};

在我的系统上,非多态 Zsizeof(Z) == 4 bytes,与 int 相同。

struct X { int x; virtual ~X() {}; };
struct Y : X {};
struct Z : Y {};

现在在使 Z 多态后,sizeof(Z) == 16 字节。所以 Z 的数组现在大了 300%,因为每个 Z 实例都必须在运行时存储其类型信息。

关于c++ - 在 C++11 中检查对象类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17204487/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com