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

时间:2013-07-29 20:33:14

标签: c++ class inheritance c++11

在学习考试时遇到这个问题,会对短暂的言论进行审查 如果我有class Object和另一个class Point : public Object
现在,如果我得到Object& O1Object& O2,但Object也可以Point ...... 所以我的主要问题是如何检查它们是否都是Point因为我需要访问Object没有的字段

以下是两个类:

  

类对象{
  公众:
  一些功能
  };

     

类点:公共对象{
  双x;
  双y;
  公众:
  相同的功能不同的实现
  };

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

提前致谢

4 个答案:

答案 0 :(得分:7)

您可以使用dynamic_cast

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

如果o的动态类型是Point或从if派生,p中的代码将在o随时可用的情况下执行(静态类型) Object的{​​{1}}是{。}}。

如果您已经知道它是Point,则可以使用参考

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

要使其工作,virtual中必须至少有一个Object函数(如果只有析构函数)。

答案 1 :(得分:3)

一般来说,如果你“需要”知道这一点,那你就错了。有一些例外,但通常,您不需要知道您正在“使用”哪种类型的对象。您的不同函数应声明为virtual,以便使用Object执行某些操作的代码只需调用Point中的相关函数(如果对象为Point类型对象。

如果您想访问xy,您应该通过虚拟函数间接执行此操作,该函数执行需要在xy执行的任何操作。如果你真的需要触摸xy当你只有({1}}的引用或指针时,你只是处于错误的级别。

答案 2 :(得分:1)

您可以信赖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);
}

答案 3 :(得分:0)

它可能很草率但是如果你有一个指针或对象的引用,你总是可以调用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;
}