在学习考试时遇到这个问题,会对短暂的言论进行审查
如果我有class Object
和另一个class Point : public Object
现在,如果我得到Object& O1
和Object& O2
,但Object
也可以Point
......
所以我的主要问题是如何检查它们是否都是Point
因为我需要访问Object
没有的字段
以下是两个类:
类对象{
公众:
一些功能
};类点:公共对象{
双x;
双y;
公众:
相同的功能不同的实现
};
我想访问x,y但是我需要先确定它是Point
。
提前致谢
答案 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
类型对象。
如果您想访问x
和y
,您应该通过虚拟函数间接执行此操作,该函数执行需要在x
和y
执行的任何操作。如果你真的需要触摸x
和y
当你只有({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;
}