【问题标题】:C++ covariance in parameters参数中的 C++ 协方差
【发布时间】:2012-08-03 00:05:14
【问题描述】:

我想知道为什么 C++ 不支持参数的协变,如下例所示,或者是否有办法实现它?

class base {
public:
virtual base* func(base * ptr) { return new base(); }
};

class derived : public base {
 public:
 virtual derived* func(derived * ptr) override { return new derived(); } //not allowed
};

【问题讨论】:

  • 一个更有趣的问题是为什么不支持论点的逆变。
  • 我的猜测是,这是一个很少被调用的函数。如果是这样,请使用dynamic_cast<derived*> 获取派生值;这也使您有机会为错误的参数抛出异常。

标签: c++ virtual covariance


【解决方案1】:

返回类型是允许的,因为 derived 继承自 base,但函数参数不能工作 - 并非所有 base 实例也是 derived。在指向base 且参数不是derived 的指针上调用func 的情况下应该发生什么?最衍生的实现是不可调用的。

【讨论】:

  • 这违反了liskov替换原则。
  • 有解决办法吗?在 Java/C# 中,您可以只使用强制转换,但在 C++ 中,您的对象将被切片。
  • @Winter 除非您按值传递,否则没有切片(对于多态函数,按值传递会很奇怪,这是这里的问题)。通过指针传递(如问题中所示)或引用/shared_ptr/unique_ptr 将全部工作并且可以转换,而无需像任何其他 OO 语言一样进行任何切片。唯一的问题是使用哪种强制转换来保证安全并适合您的类型层次结构,这归结为在 dynamic_cast 或 static_cast 之间进行选择,并严厉警告用户不要破坏您强加的不成文合同。不过,您可能想重新审视您的设计决策。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-22
  • 1970-01-01
  • 1970-01-01
  • 2012-07-14
  • 2013-06-18
相关资源
最近更新 更多