假设有两个类,Foo和ImitateFoo。 ImitateFoo实现了一个隐式的强制转换运算符,就像Foo一样。
class Foo
{
public:
int DoFoo() { return 1; }
};
class ImitateFoo
{
private:
Foo f;
public:
operator Foo&() { return f; }
};
我想对ImitateFoo采取行动,就像我在Foo上做的那样。特别是调用它的方法。
ImitateFoo imitator;
Foo& f = imitator; // implicit cast works
f.DoFoo();
static_cast<Foo&>(imitator).DoFoo(); // static cast works as well
imitator.DoFoo(); // does NOT compile -- desired behaviour!
不幸的是,最后一种方法无法编译(至少在VS 10.0中)。 由于某些原因,不能使.-运算符超载。
我有什么建议可以达到预期的行为吗?是否可能以某种方式增加cast-operator对。-operator的绑定优先级?
编辑:为什么我不能将继承用作最明显的解决方案
我必须重新实现一堆框架类。 Foo
类似于其中一个,它在遗留代码中用作全局对象(我不能更改)。
由于我现在需要进行单元测试,我需要控制这些全局对象的状态。这与完成类似的方式完成 PIMPL idiom建议。
在这种情况下,ImitateFoo
类只有一个状态:它的实现被注入并可能在运行时被更改。所有方法调用都会重定向到此Foo
实例。所以实际上我可以实现上面的例子就像在DoFoo
中创建一个ImitateFoo
非虚函数一样简单,并重定向到其current实现方法。事实上,这就是我现在正在做的事情。
这对于方法和运营商都很有效。但是它导致了大量的膨胀代码,它不会重定向。
与通过它自己重定向每个方法和操作符调用相反,我想退后一步,看看是否可以让ImitateFoo
表现得像它的底层实现。
答案 0 :(得分:0)
在像Python这样的动态语言中,您可以将所有非明确定义的方法委托给另一个对象(此处为字段f
)。但是AFAIK在C ++中是不可能的。
如果继承不是可接受的解决方案,您可以明确地委托您希望ImitateFoo
进行处理的所有方法,使用duck typing而不是继承:
class ImitateFoo
{
private:
Foo f;
public:
operator Foo&() { return f; }
int DoFoo() { return f.DoFoo(); } // explicit delegation
};
它不是你想要的那么自动,但至少是:
imitator.DoFoo();
将正确编译并运行。
答案 1 :(得分:0)
看起来有点像X Y问题,而你提出的解决方案虽然在概念上很优雅,但我不相信它在C ++中是可能的。
运行一个与你类似的问题我已经使用宏来隐藏重复的代码,在你的情况下将是转换(考虑到你想要避免的实际问题是重写每个函数/ operator,主要目标是减少要写入的代码量。)
这是一段代码段
#define CAST(x) (static_cast<Foo&>(x))
...
ImitateFoo f;
CAST(f).DoFoo();