我确实不推荐这个,但你可以定义这种模棱两可的方法并通过不同的接口使用它们。
(以下至少适用于使用 -std=c++11 的 gcc 4.8.0。)
考虑两个接口:
class IInterface1
{
public:
virtual void funky(int i) = 0;
virtual void funky(int i, int j) = 0;
};
class IInterface2
{
public:
virtual void funky(int i, int j = 0) = 0;
};
IInterface1 为不同的参数重载了两次 funky 方法,即相同的方法名称,但一个采用单个 int,而另一个采用两个 int。注意在接口实现中,funky 方法需要有两个实现(一个用于一个参数,另一个用于两个参数)。
IInterface2 有一个 funky 方法,在调用时采用一个或两个整数。如果未明确提供,则第二个 int 为默认值。请注意,在接口实现中,funky 方法只需要 一个 实现(并且无论在调用期间提供一个还是两个参数,它总是需要两个参数)。
实现两个接口的类:
class Foo : public IInterface1, public IInterface2
{
public:
void funky(int i) override
{ printf(" funky(int i) -> funky(%d)\n", i); }
void funky(int i, int j = 0) override
{ printf(" funky(int i, int j = 0) -> funky(%d, %d)\n", i, j); }
void funky(int i, int j = 0, int k = 0)
{ printf(" funky(int i, int j = 0, int k = 0) -> funky(%d, %d, %d)\n", i, j, k); }
};
为了说明,Foo 还添加了funky 方法的第三个重载版本,一个接受三个参数(一个强制,两个可选)。
Foo 现在可以如下图所示使用。 Foo、master的实例可以直接使用,也可以让不同的客户端访问master对象的不同接口。
Foo master;
IInterface1& client1 = master;
IInterface2& client2 = master;
// AMBIGUOUS: master.funky(1);
// AMBIGUOUS: master.funky(2,3);
puts("master.funky(4, 5, 6);");
master.funky(4, 5, 6);
puts("client1.funky(7);");
client1.funky(7);
puts("client1.funky(8, 9);");
client1.funky(8, 9);
puts("client2.funky(10);");
client2.funky(10);
puts("client2.funky(11, 12);");
client2.funky(11, 12);
这将产生以下输出:
master.funky(4, 5, 6);
funky(int i, int j = 0, int k = 0) -> funky(4, 5, 6)
client1.funky(7);
funky(int i) -> funky(7)
client1.funky(8, 9);
funky(int i, int j = 0) -> funky(8, 9)
client2.funky(10);
funky(int i, int j = 0) -> funky(10, 0)
client2.funky(11, 12);
funky(int i, int j = 0) -> funky(11, 12)
总而言之,类可能具有明显冲突的方法重载版本。在调用方法时必须解决歧义(否则代码将无法编译)。
PS:同样,由于上述做法违反了KISS原则,我不宽恕它。