我正在编写使用讨厌的非C ++ 11代码的类的重写。不幸的是,我不允许更改父类。
它有两个同名的方法,其中一个被子类覆盖。方法也作为参数传递给方法。我想在这里有函子,但正如我之前写的,我无法更改CLassA。
简化的代码如下所示:

家长班:

class CLassA
{
public:
    typedef void  (CLassA::*Method_t)(int x, int y);
    int ForAll(Method_t action, int y);
    virtual void MethodA(int x);
    virtual void MethodA(int x, int y);
};

int CLassA::ForAll(Method_t action, int x)
{
    (this->*action)(x, x);
    return x;
}

void CLassA::MethodA(int x)
{
    printf("CLassA::MethodA: %d\n", x);
    ForAll(&CLassA::MethodA, x);
}

void CLassA::MethodA(int x, int y)
{
    printf("\tCLassA::MethodA: %d %d\n", x, y);
}


我的第一个替代:

class CLassB : public CLassA
{
public:
    void MethodA(int x, int y) override;
};

void CLassB::MethodA(int x, int y)
{
    printf("\tCLassB::MethodA: %d %d\n", x, y);
}


我的第二个替代:

class CLassC : public CLassB
{
public:
    void MethodA(int x) override;
};

void CLassC::MethodA(int x)
{
    printf("CLassC::MethodA: %d\n", x);
    ForAll(&CLassC::CLassA::MethodA, x);
}


调用例程:

int main(int argc, char** argv)
{
    CLassA A;
    A.MethodA(1);

    CLassB B;
    B.CLassA::MethodA(2);

    CLassC C;
    C.MethodA(3);
    return 0;
}


输出(link):

CLassA :: MethodA:1
    CLassA :: MethodA:1 1
CLassA :: MethodA:2
    CLassB :: MethodA:2 2
CLassC :: MethodA:3
    CLassB :: MethodA:3 3


我绝对不喜欢,我必须将名称空间添加到引用中并调用(ForAll(&CLassC::CLassA::MethodA, x);B.CLassA::MethodA(2);)。

您能否给我一个提示,如何避免这些丑陋的表示法?

最佳答案

当您仅覆盖潜在的重载方法之一时,添加一个“ using BaseClass :: MethodA;”。给你的孩子上课。

因此,ClassB声明变为;

class ClassB : public ClassA {
 public:
  using ClassA::MethodA;
  virtual void MethodA(int x, int y) override;
};


而且您的定义没有改变。然后,您可以执行B.MethodA(2);,而无需坚持使用中间ClassA消除歧义。

10-06 01:41