C++ 如何用隐式cast算子模拟类行为

C++ 如何用隐式cast算子模拟类行为,c++,casting,operator-overloading,C++,Casting,Operator Overloading,假设有两个类,Foo和simulatefo。 模仿Foo实现了一个隐式cast操作符,其行为类似于Foo class Foo { public: int DoFoo() { return 1; } }; class ImitateFoo { private: Foo f; public: operator Foo&() { return f; } }; 我想模仿Foo,就像我模仿Foo一样。特别是调用它的方法 ImitateFoo imitator; Fo

假设有两个类,Foo和simulatefo。 模仿Foo实现了一个隐式cast操作符,其行为类似于Foo

class Foo
{
public:
    int DoFoo() { return 1; }
};

class ImitateFoo
{
private:
    Foo f;

public:
    operator Foo&() { return f; }
};
我想模仿Foo,就像我模仿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!
模仿者模仿者;
Foo&f=模仿者;//隐性演员作品
f、 DoFoo();
静态_cast(模仿者).DoFoo();//静态cast也可以工作
simulator.DoFoo();//不编译--期望的行为!
不幸的是,最后一种方法没有编译(至少在VS10.0中是这样)。 由于某些原因不可能使操作员过载

有什么建议可以让我达到期望的行为吗?是否有可能增加cast操作符对。-操作符的绑定优先级

编辑:为什么我不能将继承作为最明显的解决方案

我必须重新实现一堆框架类
Foo
类似于其中的一个,它在遗留代码中用作全局对象(我不能更改)

因为我现在需要单元测试,所以我需要控制这些全局对象的状态。这与 提议

在这种情况下,
simulatefo
类只有一个状态:它的实现被注入,并且可能在运行时被更改。所有方法调用都重定向到此
Foo
实例。因此,实际上我可以很容易地实现上面的示例,只需在
simulatefo
中创建一个
DoFoo
非虚拟函数,并重定向到当前的实现方法。这就是我现在正在做的

这对方法和运算符都非常有效。但是它会导致大量膨胀的代码,而这些代码除了重定向之外什么也做不了


与自己重定向每个方法和操作符调用相反,我想退一步,看看是否有可能让
simulatefo
像它的底层实现一样工作。

在Python这样的动态语言中,您可以将所有未明确定义的方法委托给另一个对象(这里是field
f
). 但是在C++中,不可能。

如果继承不是一个可接受的解决方案,您可以明确地委托您想要的所有方法
simulatefo
do-process,以一种代替继承的方式:

class ImitateFoo
{
private:
    Foo f;

public:
    operator Foo&() { return f; }
    int DoFoo() { return f.DoFoo(); } // explicit delegation
};
它不像您希望的那样自动,但至少:

imitator.DoFoo(); 

将正确编译和运行。

看起来有点像XY问题,而你提出的解决方案虽然在概念上很优雅,但我不相信C++中有可能。

运行在一个与您的问题有点类似的问题中,我使用宏来隐藏重复的代码,在您的情况下,这就是强制转换(考虑到您想要避免的实际问题是重新编写每个函数/运算符,主要目标是减少要编写的代码量)

下面是一段代码片段

#define CAST(x) (static_cast<Foo&>(x))
...
ImitateFoo f;
CAST(f).DoFoo();
定义强制转换(x)(静态强制转换(x)) ... 模仿; CAST(f.DoFoo();
如果可能的话,我会很惊讶。但是我喜欢对C++的简短回答感到惊讶,不,这是不可能的,但是对于这个例子,你可以简单地让
simulatefo
继承
Foo
。你能提供更多关于你为什么需要这样做的细节吗?有一个允许超负荷的方法。但这至少要到2017年才会成为标准。我建议你不要依赖于内隐行为。若你们混合使用这两个类,你们可能会产生令人困惑的结果。若这一类符合标准,你们将能够做这样的事情。我的主要限制是无论如何都不更改遗留代码,因此不幸的是,这不是解决方案。我假设复制每个方法和操作符是唯一的可能性。