访问 class 变量

Access to class variable

我在访问对象时遇到问题,该对象是 class 的变量。继承关系如下:

#include "X.h"

class Y
{   
    X object; 

public:
    X & getObject();
};

然后另一个file/class:

#include "Y.h"

class Z : public Y
{
    X object2;
public:
    X & getObject2();
};

最后是一个 class,它获得了指向对象的指针向量。

 #include "Z.h"

 class XYZ
 {
    vector<Y*> cont;  //contains objects of class type Z and Y
 };

如果我想访问 object 变量,我只需写

cont[index]->getObject();

但是没有办法访问object2,编译器甚至没有看到getObject2()这样的方法。估计是我描述的不够清楚,不过还是希望大家帮帮我。

您的第一个问题是确定您是否可以调用getObject2方法。代码中的注释说向量包含两种类型的对象,那么您如何确定任何一个特定对象是 Z 而不仅仅是 Y?如果它是 YgetObject2 方法不可用,您不能尝试调用它。

您有多种选择。以下是其中一些:

  • 一种解决方案是对两种不同的类型使用两个单独的向量:

    vector<Y*> conty;
    vector<Z*> contz;
    

    但是,这不会保持不同对象类型之间的顺序。这是否是一个问题取决于您的目的。

  • 另一个解决方案是将指针转换为所需的类型 -

    (Z *)(cont[index])->getObject2();
    

    ...但是只有知道指向对象的实际类型时才能这样做。如果您不确定,可以使用 dynamic_cast

    Z *z = dynamic_cast<Z *>(cont[index]);
    if (z != nullptr) {
        z.getObject2();
    }
    
  • 另一个解决方案是将 getObject2 添加到基 class、Y 中,并使其成为虚拟的,以便可以在 [=15] 中覆盖它=].您可以在 Y 中实现,只需 return nullptr。您需要更改 getObject2 的 return 类型,以便它 return 是指针而不是引用。

    class Y
    {   
        X object; 
    
    public:
        X & getObject();
        virtual X * getObject2();
    };
    

哪个选项最好取决于您的具体要求。

如果您想尝试真的 来调用object2(),您可以尝试使用dynamic_cast 来键入Z*。在 documentation 中,您对如何使用它有完整的解释(例如:如果您将指针传递给 Y 类型的对象,它将无法返回 NULL 指针)

Z* p_z = dinamic_cast<Z*> (cont[index])
if (p_z)
   std::cout << p_z->getObject2();

contY*的向量。这意味着它的成员仅公开在 Y class 上定义的 API。 getObject2() 仅在其后代上定义。即使向量中的成员实际上是 Z 的实例,只要它们作为类型 Y 的实例访问,那么只有 Y 的接口可用。

如果您希望 getObject2() 可用,您需要执行以下三项操作之一:
1.在Y
中增加一个虚getObject2()方法 2.将getObject2()函数完全移动到Y
3. 将cont设为vector<Z*>

看来你需要虚函数。您的代码可能会以这种方式更改:

#include "X.h"

class Y
{   
    X object; 

public:
    virtual X & getObject()
    {
        return object;
    }

};

和:

#include "Y.h"

    class Z : public Y
    {
        X object2;
    public:
        virtual X & getObject()
        {
            return object2;
        }
    };

所以在

的任何调用
cont[index]->getObject();

在运行时,可以查看某个实体的虚拟 table,指向它的指针在 cont[index] 中。如果它是指向 Y 对象的指针,则调用 Y class 的 getObject(),如果它是指向 Z 对象的指针,则调用 Z class 的 getObject()。