1

假设我有这段代码;

class Ingredients{
    public:
        Ingredients(int size,string name);
        int getsize();
    private:
        string name;
        int size;
};

struct Chain{
    Ingredients* ing;
    Chain* next;  
}

在我的主要;

int main()
{
    cout<<typeid(Chain).name()<<endl;
    cout<<typeid(Chain->ing).name()<<endl;
    cout<<typeid(Chain->next).name()<<endl; 

}

我的标题是;

#include <iostream>
#include <typeinfo>

using namespace std;

最后输出;

P8Chain
P12Ingredients
P8Chain

所以我的问题是,这种类型在代码中使用它是否可靠?如果类型正在改变(因为 P8 和 P12 的东西,我不确定它是否会相同)从计算机到计算机。这种类型不可靠。你有什么意见?

他们也不会在每次运行时都发生变化。

4

4 回答 4

3

它们取决于你的编译器,所以不要在你的代码中使用它们。

C++ 标准说明了以下有关typeid第 5.2.8 节)的内容:

typeid表达式的结果是静态类型const std::type_info和动态类型const std::type_infoconst 名称的左,其中名称是从.std::type_info

如果你想要某种RTTI ,你可以做的是

if (typeid(myobject) == typeid(Chain)) {
    do_something();
}
于 2012-11-02T22:00:19.483 回答
3

这取决于您所说的“类型”。类型的或多或少的标准定义是类型可以采用的一组值和操作,这将从一台机器到另一台机器发生变化,因为 的大小int会改变,或者字符串的最大长度。另一方面,类型是编译器和 C++ 标准认为的类型,这是非常真实的意义,它非常粗略地对应于,或至少由作用域名称标识。最后,std::type_info::name()功能严重不足。充其量,它对调试很有用(例如,记录调用函数的实际派生类),并不是所有的编译器都提供这一点。就标准而言,编译器总是可以返回一个空字符串,并且仍然符合标准。

于 2012-11-02T22:19:31.033 回答
1

“类型”一词有多种含义。

就类型理论而言,C++ 结构根本没有真正定义类型。

更有用的是,C++ 语言标准以一种可以严格接受的方式讨论类型,即使它从未非常严格地定义该术语。在这些术语中,结构声明确实定义了一个唯一且一致的类型。

对你的 C++ 编译器(和 C 链接器)来说,可能更有用的是,类型由诸如内存布局、错位名称、成员名称和类型列表、指向特殊和普通成员函数的指针、可能指向 vtable 的指针之类的东西表示和/或 rtti 信息等。从实施到实施,这将是不同的。在具有相同实现的构建之间,即使没有相关代码更改,某些细节(例如指针指向的位置)也可能会更改,但您可能可以定义一个有用的信息子集,您可以有效地将其称为不会更改的“类型”。

除此之外,type_info标准第 18.5.1 节定义的实例不能在明确定义的范围内更改,并且typeid第 5.2.8 节定义的结果是该实例或仍然与之相等的兼容对象. 因此,在我看来,如果可以同时type_info从两个不同的运行中加载实例,operator==则必须返回true. 但是,实际上不可能type_info从两个不同的运行中加载实例(例如,不要求它们以任何方式可序列化),因此这可能不相关。

最后,由 18.5.1 定义的名称typeid().name()是任何实现定义的 NTBS。它可以在同一运行中的构建、运行甚至调用之间发生变化。它可能总是空的。实际上,它通常对调试有用,但不能保证——即使是这样,也无济于事,因为“对调试有用”并不一定意味着“在一个运行并持续运行”。

如果您询问特定的编译器,编译器的文档可能会提供比标准要求更严格的保证。例如,我相信在各种平台上,g++ 保证它将使用 CodeSourcery 中定义的 C++ ABI,并且不会在次要编译器版本中更改 ABI 版本,并将使用 ABI 中定义的错误名称作为type_info名称。这意味着将二进制文件带到另一台计算机不会影响名称,甚至在具有相同平台和 g++ 版本的另一台计算机上重新编译源代码也不会影响名称。

于 2012-11-02T22:41:20.150 回答
1

根据标准,name() 是实现定义的(以及根据 Stroustrup 书 - 参见第 3 版第 415 页)

于 2012-11-02T22:08:21.023 回答