我需要将对象传递给类,并根据此传递对象中的值,让类使用两组方法中的一种。我不会在这堂课中以任何方式改变b。我希望这对用户尽可能透明,以便它们传入对象,然后只是正常调用方法,所以我试图避免需要单独管理Foo1和Foo2类。
e.g。
class Foo
{
public:
Foo(Bar & b){
useScheme1 = b.a == 1;
}
void methodA(){
// call either A1 or A2
}
void methodB(){
// call either B1 or B2
}
protected:
bool useScheme1 = false;
// methods A1, A2, B1 and B2 defined as protected functions
.
.
.
};
答案 0 :(得分:3)
这种功能完全是什么动态多态?我绝对建议使用一个非常基本的创建函数和Foo
+孩子,如下所示:
namespace foo_library {
class Foo
{
public:
virtual void methodA() = 0;
virtual void methodB() = 0;
virtual ~Foo() {}
};
class Foo1 : public Foo
{
virtual void methodA()
{
// Do A1 here.
}
virtual void methodB()
{
// Do B1 here.
}
};
class Foo2 : public Foo
{
virtual void methodA()
{
// Do A2 here.
}
virtual void methodB()
{
// Do B2 here.
}
};
Foo* create_foo(const Bar& b)
{
if(b.a == 1) return new Foo1;
return new Foo2;
}
}
// Then you use it like this:
int main()
{
Bar b; // Initialize it.
std::unique_ptr<foo_library::Foo> foo = foo_library::create_foo(b); // Use the appropriate smart pointer for your ownership needs.
foo->MethodA(); // Decides which to do based on the bar.
}
答案 1 :(得分:0)
一般来说,使用函数指针来实现你想要做的就是问题的C解决方案。而且你用C ++编写代码,而不是C.所以这说明了一切。
也就是说,在这里使用指针可以灵活地做出最后一分钟的运行时决策,也许是基于其他一些参数的值(例如,如果你需要选择使用哪个函数,那些函数可能会有所不同)很多基于对象,但一些其他运行时条件)。
除了上面提到的场景之外,我还使用了多态性;在我看来,它使代码更加透明。
答案 2 :(得分:0)
这是C ++ 11。 pImpl类型擦除。
struct Foo {
Foo( Bar const& b ):
pScheme( makeScheme1(b.a==1) )
{}
void methodA() { pScheme->methodA(this); }
void methodB() { pScheme->methodB(this); }
private:
struct Scheme {
virtual void methodA(Foo* self) const = 0;
virtual void methodB(Foo* self) const = 0;
virtual ~Scheme() {};
};
std::shared_ptr<const Scheme> pScheme;
struct Scheme1:Scheme {
void methodA(Foo* self) const override {
std::cout << "Scheme1::methodA[" << self << "]\n";
}
void methodB(Foo* self) const override {
std::cout << "Scheme1::methodB[" << self << "]\n";
}
};
struct Scheme2:Scheme {
void methodA(Foo* self) const override {
std::cout << "Scheme2::methodA[0x" << self << "]\n";
}
void methodB(Foo* self) const override {
std::cout << "Scheme2::methodB[0x" << self << "]\n";
}
};
std::shared_ptr<const Scheme> makeScheme( bool bScheme1 ) {
if (bScheme1) { return std::make_shared<Scheme1>(); }
else { return std::make_shared<Scheme2>(); }
}
};
现在,您可以根据Foo
构建Bar
,根据Scheme
的参数构建内部b
。
在Scheme
Foo* self
内传递Foo
,以便您可以访问Foo
的数据,以备不时之需。
这里有继承,但它是客户不关心的实施细节。您的Foo
就像一个值类型,而不是一个指针类型,这使它更容易使用。您甚至可以通过Foo
分配另一个Scheme
,它只是有效(源的方案是共享的)。
如果您想支持Foo
- 少pScheme
,则需要在解除引用前检查Foo
。就目前情况而言,移动methodA
无法安全地调用methodB
或{{1}}。