【问题标题】:How to prevent a pointer of base class to point to derived class?如何防止基类的指针指向派生类?
【发布时间】:2020-04-07 11:12:50
【问题描述】:

我遇到了如下类似的问题。

class Animal
{
   void* value;
   public:
   Animal() {}
   void* getValue() {return value;} 
}

class IntAnimal : private Animal
{
  public:
  IntAnimal() {}
  int getValue() {return (*(int*)Animal::getValue());}
}

基本上基类返回 void*,但派生类返回常规类型(int、double、char 等)。

我需要做:

  1. 我们可以:Animal* intAnimal = new IntAnimal(); int x = intAnimal->getValue();我认为这是不可能的。

  2. 阻止他人这样做:Animal* intAnimal = new IntAnimal();

如何防止别人做 (2) ?谢谢。

编辑:是的,这是一个糟糕的设计,我应该使用模板。但是,有没有其他方法可以解决这个问题?

【问题讨论】:

  • 但是.. 为什么?动物不应该是模板吗?或者...如果 value 不代表任何东西,为什么它会存在于 Animal 中?为什么getValue 不只是一个虚函数 = 0 并且值在 IntAnimal 中存储为 int?简而言之,你想表达什么?
  • 是的,Animal 应该 100% 成为模板。这是一个糟糕的设计。但是为了使事情变得不切实际,不切实际地困难,我被问题要求使用 void* 而不是模板
  • @user3192711 "asked":这是学校的作业吗?
  • 不是作业,只是我读到的一个问题。显而易见的解决方案是使用模板。但是没有模板有没有办法解决这个问题?

标签: c++ inheritance stack void void-pointers


【解决方案1】:

你无事可做。

您当前的代码首先禁止其他人使用new IntAnimal();,因为构造函数是private

即使你改变它,你的条件仍然满足。由于Animal 基类被继承为private,因此外部代码无法访问它并且隐式强制转换格式不正确。

Animal* intAnimal = new IntAnimal();

不会编译。

在类和friends 内部,基类和构造函数始终是可访问的,这种情况永远不会出现问题。


如果AnimalIntAnimal 继承为public,则不可能阻止从IntAnimal*Animal* 的隐式转换。


另请注意,继承为 private 不会阻止代码显式转换为 Animal*。任何外部代码都可以始终使用 C 样式转换

Animal* intAnimal = (Animal*) new IntAnimal();

这里的行为等同于隐式强制转换,不同之处在于它忽略了基类的可访问性,并且无论Animal是继承为private还是public,都会成功。

【讨论】:

  • 对不起。 IntAnimal 里面的东西是公开的。我已经编辑了帖子
  • @user3192711 它并没有真正改变答案,只要继承是private
  • 哦。我已经习惯了 Base *base = new Derived() 以至于我忘记了它有时是不可能的。关键字是私有继承。谢谢
猜你喜欢
  • 1970-01-01
  • 2014-06-16
  • 2022-01-03
  • 1970-01-01
  • 2016-02-19
  • 1970-01-01
  • 2020-02-11
  • 1970-01-01
  • 2016-07-03
相关资源
最近更新 更多