迭代向量时 typeid.name() 不会改变。动态转换和 typeid 基类指针

2023-12-01

答:总之用虚函数!因此,实际上不要将其用作良好的设计,但出于学习目的,请阅读!

首先我想说我正在使用 c++ 和 Qt 我有一个形状指针向量(基类)

编辑: doSomething() 不是基类的成员,而是派生类的成员。这就是为什么我使用dynamic_cast 将 Shape* 获取到 Derived* 以便我可以访问它。我这样做实际上只是出于好奇,也为了其他人了解 c++ 的类型系统

    #include <vector>
    using namespace std;
    vector<Shape *> vec;

我推回一些形状的派生类

    vec.push_back(new Square());
    vec.push_back(new Circle());

好的,然后我得到一个迭代器到开头

    vector<Shape *>::iterator tmp = vec.begin();

这里我想迭代向量

    for(;tmp != vec.end(); ++tmp)
    {
        if(typeid(**tmp).name() == typeid(Square).name())
        {
            Square * sptr = dynamic_cast<Square *>(*tmp);
            sptr->doSomething();
        }
        else if(typeid(**tmp).name() == typeid(Circle).name())
        {
            Circle * cptr = dynamic_cast<Circle *>(*tmp);
            cptr->doSomething();
        }
    }

然而,两者都会产生 Square 输出;不是第二个圆圈。我尝试比较 typeid 的内存位置

Like so:

    &typeid(**tmp) == &typeid(Square)

对于圆也是如此,但 tmp 总是会在上面的情况下产生正方形,并且当之后立即与圆运行时...动态转换是否对整个矢量进行了一些操作,我只是错过了 typeid() 工作原理的一些东西?

编辑: 这是答案,感谢 user4581301 (我也添加了一些东西!):

#include <iostream>
#include <vector>
#include <typeinfo>

struct Shape
{
    virtual ~Shape(){} //Something here must be virtual or pure virtual!
};

struct Circle: Shape
{
    void doSomething(){std::cout << "Circle" << std::endl;}
};
struct Square: Shape
{
    void doSomething(){std::cout << "Square" << std::endl;}
};

int main()
{
    std::vector<Shape *> vec;
    vec.push_back(new Square());
    vec.push_back(new Circle());
    std::vector<Shape *>::iterator tmp = vec.begin();

        for(;tmp != vec.end(); ++tmp)
        {
            if(&typeid(**tmp) == &typeid(Square))
            {
                Square * sptr = dynamic_cast<Square *>(*tmp);
                sptr->doSomething();
            }
            else if(&typeid(**tmp) == &typeid(Circle))
            {
                Circle * cptr = dynamic_cast<Circle *>(*tmp);
                cptr->doSomething();
            }
        }


}

这按预期工作doSomething as a virtual功能。如果不是virtual,那么编译本身就会失败(如果里面没有其他函数的话)Shape类是virtual)。如果源类型不是多态的,动态转换将会失败。

如果是virtual,您无需执行正在执行的操作来确定类型。让多态发挥其魔力。您可以像这样缩短代码:

#include <iostream>
#include <vector>

class Shape { public: virtual void doSomething() {std::cout << "In Shape\n";}};
class Circle: public Shape {public: void doSomething() {std::cout << "In Circle\n";}};
class Square: public Shape {public: void doSomething() {std::cout << "In Square\n";}};

int main() {
    std::vector<Shape *> vec;
    vec.push_back(new Square);
    vec.push_back(new Circle);

    for(auto tmp = vec.begin();tmp != vec.end(); ++tmp)
    {       
        (*tmp)->doSomething();        
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

迭代向量时 typeid.name() 不会改变。动态转换和 typeid 基类指针 的相关文章

随机推荐

  • Prism v4 使用 DirectoryModuleCatalog 按需加载模块

    在我的引导程序中 我有以下代码来创建我的 Directory ModuleCatalog protected override IModuleCatalog CreateModuleCatalog DirectoryModuleCatalo
  • “未定义的符号_memset”

    我问了类似的问题 但我有一些更新 这确实让我感到困惑 本质上 我想使用链接器链接多个目标文件 如下所示 usr ccs bin ld o q e start master dn z defs M mapfile q list of obje
  • 如何转换 NSString 中的日期时间格式?

    我从 xml 中获得了价值2009 11 23T05 24 41 000Z 现在我想显示这样的字符串 Wed Nov 4 2009 8 00 PM Wed Nov 4 2009 9 00 PM 怎么可能呢 Use NSDateFormatt
  • 嵌套对象空值检查

    我知道如何检查嵌套对象的多种方法NullPointerException 对于 Java 8 最简单的是应用Optional
  • Android 中旋转控件的图形问题

    我的第一个 旧 Android 应用程序 悬架计算器 显示了一个我找不到解决方案的问题 旋转器控件打开some旋转器在不需要的地方显示透明线 模式是这样的 从第一个微调器控件开始 所有其他微调器都遇到此问题 因此 虽然旋转器 2 4 6 没
  • 为什么Chrome要从style属性中读取svg圆半径?

    我使用 Chrome 开发工具进行开发 我刚刚用 IE11 进行了演示 嗯 是的 我的错误是没有使用 IE 检查 并且下面的语法不是有意的 在 d3 js 中设置属性时犯了错误 但我很受伤 因为我的图表没有显示 我想了解为什么我不能更早地发
  • 如何使用 Selenium Python 在 WordPress 帖子中上传文件?

    我试图使用自动化 WordPress 帖子内容创建Selenium Webdriver Python 不幸的是 我无法上传帖子内容中的文件 我已经搜索过解决方案 但大多数都使用send keys这不适用于 WP 插入介质 见下图 在插入媒体
  • 除了 MySQL 中的所有等效项

    所以我有一个名为members的表和另一个名为group的表 组的领导者也是成员 为了检索不是领导者的成员 我做了以下操作 代码 SELECT first name last name rank FROM members EXCEPT AL
  • 谷歌地图触摸底部工作表对话框

    我的底部工作表对话框的顶部有一个谷歌地图片段 我禁用了底部工作表行为上的可拖动触摸操作 以便我可以控制地图 问题是我无法使用向上或向下触摸操作滚动地图 因为我的底部工作表可拖动已禁用 我正在考虑当用户触摸地图时禁用底部工作表行为的触摸操作
  • 想要使用 PubNub 向用户的网络浏览器发送实时更新

    考虑使用 PubNub 向用户的 Web 浏览器发送实时更新 我查看了他们的网站和材料 看起来他们有几个不同的选择 我们希望使用它向用户正在查看的网页发送实时更新 该信息很简单 例如 您刚刚收到一条消息 我们并不是在尝试实现聊天程序或类似的
  • 使用 Jackson 或其替代方案将 JSON 树解析为普通类

    如何解析该 JSON foo bar baz Hello qux World 进入该类使用Jackson或其替代方案 public class Foo private String baz private String qux public
  • 使用旋转矩形的 4 个点在 PIL 中裁剪图像

    我有一个旋转矩形的四个点的列表 其形式为 points x1 y1 x2 y2 x3 y3 x4 y4 我可以使用以下方法在 PIL 中进行裁剪 img crop x1 y1 x2 y2 但这不适用于旋转的矩形 只是为了澄清 我希望旋转生成
  • XMLHttpRequest 模块未定义/未找到

    这是我的代码 var XMLHttpRequest require xmlhttprequest XMLHttpRequest var xhr new XMLHttpRequest xhr open GET URL xhr setReque
  • Python 删除字符串

    我有这 3 个字符串 黄色 小号 弹力 成人 T21fdsfdsfs黄色 小号 弹力 成人 Tdsfs黄色 小号 弹力 成人 TD 我想删除最后一个之后的所有内容 包括逗号 所以我想删除这些部分 T21fdsfdsfs Tdsfs and
  • 为什么静态和寄存器存储类不能一起使用?

    当按以下方式定义变量时 static register int a1 0 我们得到错误 error multiple storage classes in declaration specifiers 这个错误有什么根本原因吗 为什么变量不
  • PHP服务器端帖子

    我正在尝试让服务器端 POST 在 PHP 中工作 我正在尝试将交易数据发送到支付网关 但我不断收到以下错误 信息 fopen https secure ogone com ncol test orderstandard asp 无法打开流
  • JavaScript:可选回调? [复制]

    这个问题在这里已经有答案了 我编写了一个函数 它有 3 个参数 其中一个是回调函数 如何使回调成为可选参数 而不必编写另一个没有回调参数的函数 function myFunction arg1 arg2 callback do someth
  • 从数组中返回奇数或偶数

    只是需要帮助来确定我在这个代码战争挑战中做错了什么 我意识到这对某些人来说可能很容易 但请注意我只是 Javascript 的初学者 挑战 给你一个数组 长度至少为 3 但是 可能非常大 包含整数 该数组要么完全是 由奇数整数组成或完全由偶
  • 继承鉴别器的 .NET Linq to SQL 性能问题

    我遇到了具有大量继承类的 LINQ to SQL 模型的性能问题 我隔离了这个问题 它似乎是 LINQ to SQL 生成的代码本身的某种问题 我使用 Northwind 创建了一个示例程序来充实这个问题 在这两种情况下 它都会返回 Cus
  • 迭代向量时 typeid.name() 不会改变。动态转换和 typeid 基类指针

    答 总之用虚函数 因此 实际上不要将其用作良好的设计 但出于学习目的 请阅读 首先我想说我正在使用 c 和 Qt 我有一个形状指针向量 基类 编辑 doSomething 不是基类的成员 而是派生类的成员 这就是为什么我使用dynamic