0

我最近发现使用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(). 为什么不是这样?

4

2 回答 2

4

您有两个不同的功能:A::foo()B::foo(). 尽管它们具有相同的非限定名称,但它们并不相关。B::foo()不会也不能覆盖A::foo(),因为B它不是 . 的子类A

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


using 声明,当在类中使用时,与重载有关,但与覆盖无关。这些是非常不同的概念

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

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


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
于 2013-06-27T09:16:20.363 回答
0

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

于 2013-06-27T09:08:34.180 回答