繁体   English   中英

在C ++ / Java中隐藏与重载?

[英]Hiding vs. overloading in C++/Java?

这是我记得的:

在C ++中,如果派生类定义了一个具有相同名称但与基类不同的签名(参数等)的成员函数,它将“隐藏”基础中的相应成员函数。 例如

class Base {
public:
  void virtual f(double x); 
};

class Derived : public Base {
public:
  void f(char c); 
};

int main()
{
  Derived* d = new Derived();
  Base* b = d;
  b->f(65.3);  // call f(double x)
  d->f(65.3);  // call f(char c)
  delete d;
  return 0;
}

如果我错了,请纠正我,但我认为在C ++中说“隐藏”,这也意味着Derived类不能看到'f(double x)' ,换句话说,Derived没有'f(double x)'作为从Base继承的成员函数,对吗?

在Java教程中,'hide'实际上意味着其他东西(对于静态类方法),而对于例如方法,您可以重载从base继承的方法。 查看此示例: 使用继承的重载方法

public class ClassA {
    public void method(Number n) {
        System.out.println("ClassA: " + n + " " + n.getClass());
    }
}

public class ClassB extends ClassA {            
    public void method(Integer d) {
        System.out.println("ClassB: " + d + " " + d.getClass());
    }
}

ClassA a = new ClassB(); 
a.method(3);

在C ++类型的思考中,我会得到与基于C ++中的“动态绑定”和“隐藏”思想调用A类中的'方法(数字n)'相同的结果,但是:

  1. 我仍然不确定如何用Java解释它。 链接本身解释使用'方法签名是在编译时选择'和'它实际上是从B类调用'; 但是在C ++思考中,前者是可以的,但我不认为它是从B类调用的,它应该是从A类调用,对吧?

  2. 使用继承重载方法和Java教程,“B类”被允许从“A类”和“B类”实际上可以同时看到“的方法(个数n)”和“方法(整数d)”过载功能。 所以C ++和Java正在以不同的方式处理重载,对吗? 为什么是这样? 比如在C ++示例中,如果Derived也允许重载,'d-> f(65.3)'将调用'f(double x)',而不是'f(char c)'。

谢谢,

在C ++中,对于非虚函数,每个事物都是静态的,因此对于非虚函数,您没有dynamic-binding 并且隐藏不会从继承中删除函数。 它是这样的:

当你将方法M定义为: void M(int)然后编译器实现一个函数,在内部将Base::M命名为void Base::M( Base* this, int ) 现在这个函数在代码中的某个地方实现,无法删除,只要你能够提供这个功能就可以调用它(实际上你可以在没有这个的情况下调用它)。 所以在Child我可以调用Base::M(0); 和C ++将thisChild*转换为Base*并调用M 当您定义一个函数,其名称对应于基类的名称时,您告诉编译器我更喜欢在我的类中使用该名称作为新方法或属性! 但你不删除任何东西,你可以使用using将旧的M定义带到Child

struct Base {
    void f( int ) {}
};
struct Child : Base {
    void f( char* ) {}
    using Base::f;  // Bring Base::f to this class, so I have f(char*), f(int)
};

这旁边,你可以调用f(int)甚至没有使用的using

// In the Child class
void test() {
    Base::f('c');  // Call Base::f(char)
}

// Outside of class
Child c;
((Base*)&c)->f('1');

这不是我期望C ++表现的方式。 我不希望隐藏基类方法,而是希望子类简单地重载方法,因为参数不同。 因此,编译器将知道在调用b-> f()时使用哪种方法,因为只有一种方法可用,但是当您根据参数类型调用d-> f()时,它必须确定要使用哪种方法。 如果它不能在编译时,你将被迫使用强制转换。 在你的例子中,它应该识别小数点,如果是char则使用double。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM