【发布时间】:2013-11-18 08:47:26
【问题描述】:
我正在编写一个使用讨厌的非 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);)。
您能否给我一个提示,如何避免这些丑陋的符号?
【问题讨论】:
-
我可能弄错了,但我不认为
CLassC::CLassA::MethodA中的CLassC::实际上是必需的。CLassA似乎是CLassC中的明确标识符。 -
另外,应该提到的是,因为
CLassB对MethodA的定义是非虚拟的,如果你有一个CLassC,当前被标识为CLassB或@987654336 @(例如在CLassB或类似的向量中),它将调用MethodA的CLassB版本而不是CLassC版本。我不确定这是不是有意的。 -
你能告诉我们更多关于你真正想要做什么的细节吗?例如,如果你打电话给
B.CLassA::MethodA(2),你还会打电话给B.MethodA吗?如果不是,为什么要让CLassB覆盖MethodA,如果是,为什么不直接创建一个MethodB为你调用CLassA::MethodA? -
@OmnipotentEntity
ClassB::MethodA是隐式虚拟的(否则override说明符会导致错误),我添加了显示它的输出。顺便说一句,使用警告选项-Woverloaded-virtualGCC 会警告某些虚函数被覆盖隐藏
标签: c++ c++11 overriding