2

在问之前,我曾参考过这个较旧的问题。但我仍有疑问。

struct B1 {
  virtual void fun () = 0;
};
struct B2 {
  void fun () { cout<<"B2::fun()\n"; }
  void fun (int i) {}
};
struct D : B1, B2 {
  using B2::fun;  // This line doesn't help
};

int main ()
{
  B1 *pB1 = new D;  // Error: cannot allocate 'D' because 'B1::fun()' is abstract
  pB1->fun();
}
  1. pure virtualC++ 标准不接受继承的成员函数来解析机制的任何原因?
  2. 为什么using关键字无助于解决此错误?(编译器:linux-64 g++)
  3. 哪个函数用于using关键字,B2::fun()B2::fun(int)?(该行没有歧义)
4

5 回答 5

2
using B2::fun;

只是允许您使用该B2::fun方法,但由于B1是一个抽象类,您必须实现该类的纯虚函数 fun才能创建其对象。

于 2011-04-11T05:30:43.737 回答
0

行。不过,我只是基于逻辑推理得到了第一个的答案。假设标准接受继承的方法来解析pure virtual机制,那么正常的“虚拟”功能就会有歧义。

即假设是普通的虚函数,那么和B1::fun()之间就会出现选择混乱。因此,至少在机制上最好避免考虑继承成员。B1::fun()B2::fun()virtual

于 2011-04-11T05:34:56.983 回答
0

using仅调整名称查找过程。它不会将函数导入给定范围,也不会定义新函数。

因此,您只需要定义一个新的virtual覆盖。

于 2011-04-11T05:42:57.920 回答
0

我绝不是 C++ 专家程序员,但让我试一试:

  1. 从编译器的角度来看,我认为 B1 和 B2 是两个完全不同的类,它们恰好有一个同名的方法。即使谈到 D 的范围,编译器也没有理由使用 B2 的 fun() 实现来实现 B1 的 fun()。(我想如果我们研究一下虚拟表机制,我们可能会明白一些事情。在那里我们可能会看到为什么 B2::fun() 对 B1 的 fun() 没有帮助。)

  2. “using”指令只是让符号“fun”在 D 的范围内可见。“使用”不会将任何 fun() 实现附加到 D 类(但 D 需要 B1::fun() 的实现)。

  3. 嗯......这里的“使用”指令实际上并没有“使用”(或者我们说“调用”)两者中的任何一个。“使用”只是将名称引入 D 的范围(AKA 使名称在 D 范围内可见,类似于再次声明它们)。

于 2011-04-11T05:45:33.227 回答
0

哪个函数用于使用关键字 B2::fun() 或 B2::fun(int) ?(该行没有歧义

来自 ISO/IEC 14882:2003(E) 7.3.3.12

当 using 声明将基类中的名称带入派生类范围时,派生类中的成员函数会覆盖和/或隐藏基类中具有相同名称和参数类型的成员函数(而不是冲突)。

[Example:
    struct B { 
        virtual void f(int);
        virtual void f(char); 
        void g(int); 
        void h(int);
    };

    struct D : B { 
        using B::f;
        void f(int);   // OK: D::f(int) overrides B::f(int);

        using B::g; 
        void g(char);  // OK

        using B::h; 
        void h(int);   // OK: D::h(int) hides B::h(int)
    };

    void k(D* p) {
        p->f(1);    //calls  D::f(int)
        p->f(’a’);  //calls  B::f(char)  // Notice the call being resolved
        p->g(1);    //calls  B::g(int)
        p->g(’a’);  //calls  D::g(char)
    }

— end example] 

[注意:两个 using 声明可能会引入具有相同名称和相同参数类型的函数。如果对于非限定函数名的调用,函数重载决议选择了由这种 using 声明引入的函数,则该函数调用格式错误。]

因此,在您提供的示例中,根本没有歧义。根据传递的参数,可以决定对方法的调用。

于 2011-04-11T06:00:43.907 回答