来自具有相同基类的多个类的元素的向量

Vector of elements from multiple classes that have the same base class

本文关键字:元素 向量 基类      更新时间:2023-10-16

我目前正在做一个项目,其中我需要来自多个类的对象向量,这些类共享同一个基类,这样以后我就可以从中调用方法

class basicClass
{
public:
  void seta(bool a);
  basicClass();
private:
  int a;
};
class derivedClass1 : public basicClass
{
int b;
public:
  derivedClass1();
  void methodInClass1();
};
class derivedClass2 : public basicClass
{
int c;
public:
  derivedClass2();
  void methodInClass2();
};

然后在main.cpp中,我想调用以下方法。

QVector<basicClass*> vectorINeed;
derviedClass1 *object= new derviedClass1();
qDebug() << object->basicClass::seta(true);
qDebug() << object->derivedClass1::methodInClass1();
vectorINeed.append(object);
qDebug() << vectorINeed[0]->basicClass::seta(true);
qDebug() << vectorINeed[0]->derivedClass1::methodInClass1();

甚至我认为前三个工作得很好,最后一个没有,我得到的错误是"derivedClass1'不是‘basicClass’的基"。有没有什么方法可以修复我的类,这样我就可以真正做我想做的事情?我试图将basicClass中的方法更改为virtual,但这并不能解决问题,我还尝试了一些类型转换,但要么我做错了什么,要么这不是解决问题的方法。

我真的很感激任何帮助,甚至是一些有用的提示。我也希望编辑是好的。

当您将DerivedClass的副本提供给包含BaseClass指针的向量时,实际上是将向量内的指针向下转换为BaseClass对象,这意味着您将丢失所有DerivedClass类型信息(方法、成员等)。虽然DerivedClass内容仍将存在,但它们将不再可访问。

举以下例子:

class MyBaseClass
{
public:
  MyBaseClass();
  virtual ~MyBaseClass();
  void SetValue(const int value);
  int GetValue() const;
private:
  int m_value;
};

class MyDerivedClass : public MyBaseClass
{
public:
  MyDerivedClass();
  virtual ~MyDerivedClass();
  void SetExtraValue(const std::string &value);
  std::string GetExtraValue() const;
private:
  std::string m_extraValue;
};

"MyBaseClass"创建的每个变量只保证SetValueGetValue方法可用。MyDerivedClass创建的每个变量都保证有4个方法可用,即基类中的两个方法以及SetExtraValueGetExtraValue方法。

如果您创建一个MyBaseClass指针的向量,那么您只能保证方法SetValueGetValue在该向量的内容上可用,即使内容都是MyDerivedClass

考虑一下你的例子的这个修改版本:

QVector<basicClass*> vectorINeed;
basicClass *object= new basicClass();  // <--- Create basicClass instance instead of derivedClass1 instance.
qDebug() << object->basicClass::seta(true);
vectorINeed.append(object);
qDebug() << vectorINeed[0]->basicClass::seta(true);
qDebug() << vectorINeed[0]->derivedClass1::methodInClass1(); // <--- What would happen here?

编译器不能保证向量中的对象是derivedClass1对象,而只是basicClass对象,因此不能保证methodInClass1方法可用。

在我看来,你有三个选择:

  1. 如果可以,请将矢量声明更改为QVector<derivedClass1 *> vectorINeed。或者
  2. 针对object而不是vectorINeed[0]运行方法
  3. 如果可以保证向量的内容始终为derivedClass1类型,则可以在执行methodInClass1之前使用dynamic_cast函数执行对derivedType的强制转换

尽管可以将派生类添加到基类向量中,但该向量仍然是基类向量。

因此,实际上,在添加到向量之前,您是在对基类进行"强制转换"(我说的是强制转换,但不是完全强制转换)。

要使用基类向量的派生类方法,您需要确保处理的是派生类(可能是在创建时分配了静态变量的get方法)。然后在使用函数之前,将向量中的对象强制转换回必要的派生类。

可能有更好的方法,但我需要复习一下我的C++