【问题标题】:Function that is allowed in C++ is not allowed in C#?C++ 中允许的函数在 C# 中不允许?
【发布时间】:2014-04-18 01:16:19
【问题描述】:

在 C++ 中,我们可以这样做(伪代码):

class A {
    public:
    virtual void a(A a)=0;
    }

class B : A {
    public:
    virtual void a(B b);
}

但是当我用 C# 编写等价物时:

public abstract class A
{
public virtual void a(A a){}
}

public class B : A
{
public override void a(B b){}
}

编译器给出一个错误,说 B.a 不会覆盖 A.a。为什么 C# 不允许这样做?允许这种做法是非常合理的,因为它遵循多态性原则。

【问题讨论】:

  • 你能给出一个 C# 代码示例来说明你正在尝试做什么吗?
  • 对不起,代码中的错误。
  • 我认为更好的 C# 等价物应该让类 'A' 是一个接口,而不是一个抽象类 - 这应该会给你你想要的行为。
  • @DaveDoknjas 将A 设为接口根本不会影响错误。
  • @sepp2k:它在我的测试中有效——将“A”设为接口,然后“B”实现“A”。这提供了 VictorPrograss 提到的行为 - 指向“B”的“A”引用调用“B”中定义的方法。

标签: c# c++ inheritance compiler-errors polymorphism


【解决方案1】:

代码的 C++ 版本也不会覆盖该方法。但是由于 C++ 没有 override 关键字¹,因此您不会收到错误消息,因为编译器不知道您打算重写该方法。

如果您希望在 C# 中获得与在 C++ 中相同的行为,您只需删除 override 关键字并将其替换为 new

¹它在 C++11 中可以,但我假设你没有使用它,否则你会得到一个错误。

允许这种做法是非常合理的,因为它遵循多态性原则。

不,它没有。考虑一下:

A a = new B();
a.a(new A());

如果B.a 覆盖A.a,上述代码将调用B.a 并带有参数new A()。但是B.b 接受B 类型的参数,所以这行不通。

【讨论】:

  • C++11 添加了一个 contextual 关键字 override 将其标记为错误。
  • 如果我使用new关键字,然后定义一个A引用指向一个B,然后调用方法a,我会调用B的a方法吗?
  • @VictorPrograss 正如Servy所说,不,你不会。但请注意,在您的 C++ 程序中也是如此。
猜你喜欢
  • 2011-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多