我正在尝试编写一个c ++抽象类,我无法弄清楚如何要求这个类的实现者包含一个静态函数。
例如:
class AbstractCoolThingDoer
{
void dosomethingcool() = 0; // now if you implement this class
// you better do this
}
class CoolThingDoerUsingAlgorithmA: public AbstractCoolthingDoer
{
void dosomethingcool()
{
//do something cool using Algorithm A
}
}
class CoolThingDoerUsingAlgorithmB: public AbstractCoolthingDoer
{
void dosomethingcool()
{
//do the same thing using Algorithm B
}
}
现在我想做一些很酷的事情,但没有关于如何做到这一点的细节。所以我想做像
这样的事情AbstractCoolThingDoer:dosomethingcool();
无需知道如何完成任务,但这似乎需要一个虚拟和静态的功能,这当然是一个矛盾。
基本原理是CoolThingDoerUsingAlgorithmB可能会在以后编写,希望无需重写需要很酷的事情的软件。
编辑:不确定我是否清楚自己要完成的任务。我有3个标准,我希望满足使用abstractcoolthingdoer并且不需要重写的库,即使编写了一个库从未听说过的另一个coolthingdoer。
如果您尝试编写一个不符合所需结构的coolthingdoer,那么使用该库的可执行文件将无法编译。
coolthingdoer有一些必需的静态函数。
我可能正在追逐一个糟糕的设计,所以请指出一个更好的设计。我需要工厂吗?
答案 0 :(得分:2)
也许,这样的事情会有所帮助(见ideone.com example):
#include <iostream>
class A
{
protected:
virtual void do_thing_impl() = 0;
public:
virtual ~A(){}
static void do_thing(A * _ptr){ _ptr->do_thing_impl(); }
};
class B : public A
{
protected:
void do_thing_impl(){ std::cout << "B impl" << std::endl; }
};
class C : public A
{
protected:
void do_thing_impl(){ std::cout << "C impl" << std::endl; }
};
int main()
{
B b_;
C c_;
A::do_thing(&b_);
A::do_thing(&c_);
return (0);
}
编辑:在我看来OP不需要运行时多态,而是需要编译时多态而不需要类实例(当实现隐藏在派生类中时使用static
函数,不需要实例)。希望下面的代码有助于解决它(example on ideone.com):
#include <iostream>
template <typename Derived>
struct A
{
static void do_thing() { Derived::do_thing(); }
};
struct B : public A<B>
{
friend A<B>;
protected:
static void do_thing() { std::cout << "B impl" << std::endl; }
};
struct C : public A<C>
{
friend A<C>;
protected:
static void do_thing() { std::cout << "C impl" << std::endl; }
};
int main()
{
A<B>::do_thing();
A<C>::do_thing();
return (0);
}
编辑#2:如果用户不遵守所需的模式,在编译时强制失败,这里是slight modification at ideone.com:
#include <iostream>
template <typename Derived>
struct A
{
static void do_thing() { Derived::do_thing_impl(); }
};
struct B : public A<B>
{
friend A<B>;
protected:
static void do_thing_impl() { std::cout << "B impl" << std::endl; }
};
struct C : public A<C>
{
friend A<C>;
protected:
static void do_thing_impl() { std::cout << "C impl" << std::endl; }
};
struct D : public A<D>
{
friend A<D>;
};
int main()
{
A<B>::do_thing();
A<C>::do_thing();
A<D>::do_thing(); // This will not compile.
return (0);
}
答案 1 :(得分:0)
这在我看来是正确实施bridge pattern的地方。也许这就是你(无意识地)愿意实现的目标。简而言之,您指定一个接口及其实现,然后调用您的do_thing
方法依次调用指向实现者类的指针的实现。