2011-02-01 58 views
1

去年我看到一些源代码(C++),其作者在基类中声明静态函数,但将其定义留给派生类。我记得有一个约束,即只有一个派生类被允许定义上述静态函数。委托给派生类的静态方法定义(C++)

我知道重写静态方法是不可能的,但这个技巧正是我所需要的。我只是不能让它在我的代码中工作:)有没有人知道这个功能?

让我们看看为什么这会有用。假设我们有一些基类(Shape)及其派生类(Circle,Triangle ...)。假设Shape是我的核心架构的一部分,派生类被视为插件。我不想在未来改变我的核心架构。所以我们有:

class Shape 
{ 
    //other stuff here 
    static Shape* Factory(); 
} 

class Circle:Shape 
{ 
    //other stuff here 
    static Shape* Factory(); 
} 

形状是一种抽象类,它不会实现Factory方法。方法由一个(且仅有一个)派生类实现。在实现中派生类将返回自己的新实例,所以它只是一个工厂方法。这一招使得它的作者使用的客户端类此静态方法在下列方式:

class Client 
{ 
    public Shape* shape; 
    public Client(); 
    //other stuff here 
} 

在实现构造的,他有这样的事情:

Client::Client() 
:shape(Shape::Factory()) 
{   
} 

这样,他才能够实例化“右”而不改变引擎中的核心类。当他想要在核心类中使用其他形状时,他只需要在该派生类中定义静态的Factory方法(并删除其他派生类中的现有方法)。

这样我们就有了某种“静态多态性”。我无法在网络上找到有关此技术的任何信息。它甚至有名字吗?如果在C#语言中可以实现这样的功能,我特别感兴趣? :)

在此先感谢,并抱歉我的英语不好。

回答

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()) 
{ 
} 

关于这个的好处的一点是,它的唯一get_default_shape需要包括Circle.h的实施,所有的定义需求是Shape类的前向声明。

0

嗯。我还没有看到你描述的是什么。可能是因为你引用的那段代码在包含派生类的cpp文件中定义了基类的静态函数。

// definition of Circle class 
..... 

Shape* Shape::Factory() 
{ 
    return new Circle(); 
} 

这不是在这个例子中有用的,但如果你想隐藏类的实现,只发布一个抽象基类(以减少编译时依赖)可能是一个有用的技巧。如果基类和派生类不在相同的dll/exe中,它将不起作用。

类似的东西可以在C#中通过使用IOC框架,使用泛型或在基类中注册工厂delegate来实现。我倾向于更喜欢泛型和代表。

+0

删除此评论 – Kovasandra 2011-02-02 09:38:30

+0

是的,静态方法是在派生类的cpp文件中定义的。这正是我想要实现的:)但是我无法让它在我的代码中工作,因为当我将静态类定义放入派生类cpp文件时,编译器报告基类不可访问。我想我的问题的答案是:“检查两个类是否在相同的DLL/EXE”? :)你能告诉我更多关于C#委托和相同技巧的泛型版本吗?提前致谢。 – Kovasandra 2011-02-02 09:45:24

相关问题