首页 > 解决方案 > 在 C++ 中动态更改对象的基类

问题描述

我有两个类 Sensor1 和 Sensor2,它们继承自类 Sensor。我正在创建基于运行时某些条件的基类应该是 Sensor1 或 Sensor2 的类 Camera。是否可以?

一种方法是在 Camera 中为 Sensor 创建一个指针成员,然后分配给 Sensor1 或 Sensor2(基于条件),在这种情况下,对于 Sensor 的所有方法,我需要在 Camera(setResolution 和 changeMode)中创建方法并调用相应的方法(我想避免)

class Sensor {
 public:
       Sensor(){}
       ~Sensor(){}
       void setResolution(int w, int h) {};
       void changeMode(int mode) {};
}

class Sensor1: public Sensor {
  public:
       Sensor1(){}
       ~Sensor1(){}
       void setResolution(int w, int h) {\** change based on sensor **\}
       void changeMode(int mode) {\** sensor specific implementation **\}
}

class Sensor2: public Sensor {
   public:
       Sensor2(){}
       ~Sensor2(){}
       void setResolution(int w, int h) {\** change based on sensor **\}
       void changeMode(int mode) {\** sensor specific implementation **\}

class Camera: public Sensor {
   public:
       Camera (bool flag){
       //Change base class to either Sensor1 or Sensor2 which inherits from common base class Sensor
       }
       ~Camera(){}
}

标签: c++inheritancedesign-patterns

解决方案


这是使用类似策略模式的好地方。

而不是改变你的基类Camera,让Camera包含一个指向Sensor1或的指针Sensor2。那是你检查你的状况的地方。

如果这两个类Sensor1Sensor2继承自一个共同的基类(如Sensor),则该模式实现起来非常简单。

我的 C++ 有点生疏,所以将其视为代码或伪代码,具体取决于它最终的有效性:

class Camera {
private:
  Sensor* obj;
public:
  Camera (bool flag){
    if (flag) {
      obj = new Sensor1();
    } else {
      obj = new Sensor2();
    }
  }
}

您还可以提供函数(一个 forSensor1和一个 for Sensor2)将obj字段转换为正确的类型。

关于更改基类

让我们谈谈为什么不能切换基类,以及为什么即使可以切换也是不可取的。

将您的类视为包含字段的普通结构,以及对该结构类型的变量进行操作的许多函数,名为this.

如果您从 继承Sensor1,则结构 forCamera将包含来自的所有字段和来自的Sensor1所有字段Camera。为了论证的缘故,假设所有这些加起来总共有 42 个字节的内存。假设将字段 fromSensor2与字段 from组合Camera起来最多 60 个字节。

显然,如果您随后动态更改基本类型,您的内存大小应该会更改,但在您进入构造函数时分配已经完成。因此,如果您当时可以将基本类型从 切换Sensor1Sensor2,那么您会突然有 18 个字节太少,并且更新其中的任何一个都会覆盖可能分配给其他东西的内存。那是一场等待发生的灾难。

所以我们使用像Strategy这样的模式,就像我在这里展示的那样。它更容易推理、易于实施、被广泛理解且安全。


推荐阅读