C++如何检查两个 clss 是否来自同一对象

C++ how to check if two clsses are from the same object

本文关键字:是否 对象 clss 何检查 检查 C++ 两个      更新时间:2023-10-16

在学习考试时遇到此问题,将简要说明。
如果我有一个class Object和另一个:class Point : public Object
现在,如果我得到Object& O1Object& O2,但Object也可以Point......
所以我的主要问题是我如何检查它们是否都Point因为我需要访问Object没有的字段

以下是两个类:

类对象 {
公共:
一些函数
};

类点:公共对象 {
双X;
双Y;
公共:
相同的功能不同的实现
};

我想访问 x,y,但我需要先确保它是Point

提前致谢

您可以使用

dynamic_cast

Object &o = ...;
if(Point *p = dynamic_cast<Point*>(&o)) {
  // ...
}

如果o的动态类型是Point或派生自它,则if中的代码将在p随时可用的情况下执行(o的静态类型是Object(。

如果你已经知道它是一个Point,你可以使用引用

Point &p = dynamic_cast<Point&>(o);
// ...

为此,Object中必须至少有一个virtual函数(如果只有析构函数(。

一般来说,如果你"需要"知道这一点,你就做错了。有一些例外,但作为一项规则,您不需要知道您"使用"的是哪种类型的对象。您的不同函数应声明为 virtual ,以便对Object执行某些操作的代码可以只调用 Point 中的相关函数,如果该对象是 Point 类型对象。

如果你想访问xy,你应该通过一个虚拟函数间接地做到这一点,该函数执行需要在xy上完成的任何操作。如果你真的需要触摸x,当你只有一个(一个引用或指针(一个Objecty,你只是在错误的级别。

您可以依赖C++标准库提供的类型信息。以下示例已从 cppreference.com 中提取:

#include <iostream>
#include <typeinfo>
#include <string>
#include <utility>
class person
{
  public:
   person(std::string&& n) : _name(n) {}
   virtual const std::string& name() const{ return _name; }
  private:
    std::string _name;
};
class employee : public person
{
   public:
     employee(std::string&& n, std::string&& p) :
         person(std::move(n)), _profession(std::move(p)) {}
     const std::string& profession() const { return _profession; }
   private:
     std::string _profession;
};
void somefunc(const person& p)
{
   if(typeid(employee) == typeid(p))
   {
      std::cout << p.name() << " is an employee ";
      auto& emp = dynamic_cast<const employee&>(p);
      std::cout << "who works in " << emp.profession() << 'n';
   }
}
int main()
{
   employee paul("Paul","Economics");
   somefunc(paul);
}

它可能很草率,但如果您有指向对象的指针或引用,则始终可以调用dynamic_cast。 如果指针作为 nullptr 返回,则您知道您的对象不是所需对象的派生类。

class CBase { 
      virtual void dummy(){}
};
class CDerived: public CBase {
    int a;
};
int main () {
  try {
    CBase * pba = new CDerived;
    CBase * pbb = new CBase;
    CDerived * pd;
    pd = dynamic_cast<CDerived*>(pba);
    if (pd==0) cout << "Null pointer on first type-cast" << endl;
    pd = dynamic_cast<CDerived*>(pbb);
    if (pd==0) cout << "Null pointer on second type-cast" << endl;
  } catch (exception& e) {cout << "Exception: " << e.what();}
  return 0;
}