【问题标题】:Why using cannot be used to define a virtual function?为什么不能使用 using 来定义虚函数?
【发布时间】:2013-06-24 17:00:06
【问题描述】:

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

【问题讨论】:

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


【解决方案1】:

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

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


在类中使用 using 声明时,与 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

【讨论】:

  • @VincentFourmond:很高兴为您提供帮助)
【解决方案2】:
C++ 中的

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

【讨论】:

猜你喜欢
  • 2011-03-04
  • 2016-01-07
  • 2011-05-09
  • 2012-10-06
  • 1970-01-01
  • 2022-11-21
  • 1970-01-01
相关资源
最近更新 更多