如何在 C++ 中检查指针的类型

问题描述 投票:0回答:3

我有以下代码:

// Example program
#include <iostream>
#include <string>
#include <typeinfo>

using namespace std;

class Name
{
    int a;
    int b;
};

class Name1
{
    int a;
    int b;
};


int main()
{

  Name1* name1;
  Name*  name;

  // trying to implement the following code:
  // check if name1 is of type of pointer Name1 then do someting
  // check if name is of type of pointer Name then do someting

}

如何查看指针的类型

name1

Name1和Name不继承,不能使用dynamic_cast,那如何判断指针的类型?

c++ pointers types
3个回答
8
投票

编译时微分:

您可以使用模板及其专业化:

template <class T>
bool isName(T *t) { return false; } // normal case returns false 
 
template <>
bool isName(Name *t) { return true; } // but for Name returns true

然后你可以区分你的代码,例如example

Name *n; Name1 *n1;
cout << "(1): " << isName(n) << endl;
cout << "(2): " << isName(n1) << endl;

您当然可以在条件中使用

isName()
来根据对象的类别进行处理。

从设计的角度来看,如果您有特定于类的代码,那么将它包装在一些模板中并使用上面演示的特化可能会更有趣,不是为了返回布尔值,而是做该做的事情,因为例子

template <class T>
void doMyStuff(T *t) {}  // in general do nothing 
 
template <>
void doMyStuff(Name *t) { cout << "do something with Name*"<< endl;}

template <> 
void doMyStuff(Name1 *t) { cout << "do something with Name1*"<<endl; }

...
doMyStuff(n);
doMyStuff(n1);

运行时微分:

如果需要决定任意指针的运行时间,则需要动态运行时类型信息。标准 C++ 具有 RTTI。但它要求类中至少有一个虚函数。所以,你不能只获取任何指针(例如

void*
)并找出它指向的数据!您需要一个指向有效多态类的指针。

最简洁的方法是让

Name
Name1
都继承自具有虚函数的技术通用类:

class void {
    virtual void mv() {};
};

然后您可以使用

dynamic_cast
<typeinfo>
来处理对象的类型,并轻松使用指向基础对象的指针:

void f(void *p){
    cout << "f("<<p<<"):" << typeid(*p).name() << endl;
}

然后您可以通过提供指向派生类的指针来调用此函数:

Name *n=new Name;
Name1 *n1=new Name1;
f(n);   // no risk here, it's automatic conversion to base type 
f(n1); 

请注意,为了更好的设计,您还可以将任何特定于类的行为嵌入到虚函数中,该虚函数专用于每个派生类型。但这是可靠类设计的开始,您的假设是:不相关的类。

一种更容易出错的方法是保持这些类中的每一个独立,但要确保每个类至少有一个虚函数,以确保它们是多态的并包含 RTTI 信息。

然后您可以使用危险的

reinterpret_cast
并使用对 RTTI 信息的访问。 这段代码演示原理:

f(reinterpret_cast<vvoid*>(n)); 
f(reinterpret_cast<vvoid*>(n1));
 

好像有用。然而,如果你不小心转换了一个没有虚函数的类,你的代码会在没有警告的情况下编译,但它会在执行时非常糟糕。


0
投票

可以使用boost:boost/type_index.hpp。您可以在下面找到代码:

#include <boost/type_index.hpp>
#include <iostream>

using std::cout;
using boost::typeindex::type_id_with_cvr;

struct TName
{

};

struct TName1
{

};

int main()
{
    TName* name;
    cout << "param = " << type_id_with_cvr<decltype(name)>().pretty_name() << '\n';

    if (type_id_with_cvr<decltype(name)>().pretty_name() == "TName*")
    {
        std::cout << "Variant 1\n";
    }

    TName1* name1;
    if (type_id_with_cvr<decltype(name1)>().pretty_name() == "TName1*")
    {
        std::cout << "Variant 2\n";
    }
}

结果:

参数 = TName*

变体 1

变体 2


-2
投票

您可以为此使用 typeid:

string typeToFind == "Name1 *";
if(typeToFind.compare(typeid(Name1).name()) == 0) {
    //Your code
}

它可能不漂亮,但可以解决问题。

© www.soinside.com 2019 - 2024. All rights reserved.