去年我看到了一些源代码(C ++),其作者在基类中声明了静态函数,但将其定义留给了派生类。我记得有一个约束,即只允许一个派生类定义上述静态函数。
我知道覆盖静态方法是不可能的,但这个技巧正是我所需要的。我只是无法在我的代码中使用:)有没有人知道这个功能?
让我们看看为什么这会有用。假设我们有一些基类(Shape)及其派生类(Circle,Triangle ......)。假设Shape是我的核心架构的一部分,派生类被视为插件。我不希望将来改变我的核心架构。所以我们有:
class Shape
{
//other stuff here
static Shape* Factory();
}
class Circle:Shape
{
//other stuff here
static Shape* Factory();
}
Shape是一种抽象类,它不会实现Factory方法。方法由一个(且仅一个)派生类实现。在实现中,派生类将返回自身的新实例,因此它只是一个工厂方法。这个技巧允许其作者以下列方式在客户端类中使用此静态方法:
class Client
{
public Shape* shape;
public Client();
//other stuff here
}
在构造函数的实现中,他有类似的东西:
Client::Client()
:shape(Shape::Factory())
{
}
通过这种方式,他能够在不改变引擎核心类的情况下实例化“正确”的形状派生。当他想要在核心类中使用其他形状时,他只需在该派生类中定义静态Factory方法(并删除其他派生类中的现有方法)。
这样我们就有了某种“静态多态”。我在网上找不到任何关于这种技术的东西。它甚至有名字吗?如果可以用C#语言实现这样的东西,我特别感兴趣吗? :)
提前致谢,抱歉我的英语不好。
答案 0 :(得分:0)
嗯。我还没有看到你描述的确切内容。可能是您引用的代码片段定义了包含派生类的cpp文件中的基类静态函数。
// definition of Circle class
.....
Shape* Shape::Factory()
{
return new Circle();
}
这在这个例子中没用,但是如果你想要隐藏类的实现并且只发布一个抽象基类(减少编译时依赖性),它可能是一个有用的技巧。如果基类和派生类不在同一个dll / exe中,它将无法工作。
通过使用IOC框架,泛型或通过在基类中注册工厂delegate
,可以在C#中实现类似的功能。我倾向于更喜欢泛型和代表。
答案 1 :(得分:0)
在我看来,你试图做的事情有点混乱。感觉就像是Factory类,Singleton的组合,然后试图将它们全部压回到结果类层次结构中。
我能想到的最简单(不一定是最好的)解决方案是忘记拥有Circle::Factory()
或Shape::Factory()
并且只有一个名为get_default_shape()
的免费函数。
class Shape
{
};
class Circle: public Shape
{
};
Shape * get_default_shape()
{
return new Circle;
}
Client::Client()
:shape(get_default_shape())
{
}
关于这一点的好处是它只需要包含Circle.h的get_default_shape的实现,所有定义需求都是Shape类的前向声明。