为什么使用不能用于定义虚函数?

时间:2013-06-27 09:04:20

标签: c++ inheritance virtual-functions override using-declaration

我最近发现使用using将基类函数导入到派生类的名称空间中(当它被隐藏时)。我试图用它从基类导入一个函数作为派生类中函数的实现:

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

class B {
public:
  void foo() {
  }  
};

class C : public A, public B {
public:
  using B::foo;
};


int main()
{
  C c;
}

这不会编译,因为A::foo()C中的纯虚函数。我希望using B::foo;能够实现foo()。为什么不是这样呢?

2 个答案:

答案 0 :(得分:4)

您有两个不同的功能:A::foo()B::foo()。虽然它们具有相同的非限定名称,但它们相关。 B::foo()没有也无法覆盖A::foo(),因为B不是A的子类。

C继承了AB的两个功能。您对两个基类都使用公共继承,因此在A::foo()B::foo()C 已经可见(请注意,您需要限定名称来调用函数以避免歧义)。 所以你的使用声明实际上没有效果。


使用声明在类中使用时,与 overloading 有关,但它与 overriding 无关。这些非常不同的概念

重载是关于具有相同名称但不同参数集的不同函数。

覆盖是关于多态的,即在派生类中具有不同的基类方法实现。


using声明将基类中的函数名称引入派生类,其中该名称将被另一个具有相同名称​​但不同参数的函数隐藏。例如:

class X
{  
 public:
  void func() {}
};

class Y : public X 
{  
 public:
  void func(int arg) {}
};

Y::func 不会覆盖 X::func,因为它的参数不同。此外,它还隐藏基类中的名称func,因此只能通过限定名称来调用它,例如:

X x; 
x.func(); // ok

Y y; 
y.func(1); // ok, Y::func called 
y.func(); // error, base-class name func is hidden by local name 
y.X::func(); // ok, qualified name, X::func called 

在这种情况下,using声明会将基类中的名称引入派生类,使得func可以在没有名称限定的情况下调用:

class Y : public X 
{  
 public:
  using X::func; 
  void func(int arg) {}
};

// ...

Y y; 
y.func(); // ok, X::func called

答案 1 :(得分:0)

C ++中的

using具有不同的含义,并指定您希望能够访问另一个命名空间中的函数/对象,而无需显式键入命名空间名称。它与覆盖无关。