我正处于一个班级,让我们称之为班级Generic
.这个类有成员和属性,我打算在一个std::vector<Generic>
或类似的地方使用它,处理这个类的几个实例.
此外,我想专门化这个类,泛型和专用对象之间的唯一区别是私有方法,它不访问类的任何成员(但由其他方法调用).我的第一个想法是简单地声明它virtual
并在专门的类中重载它,如下所示:
class Generic
{
// all other members and attributes
private:
virtual float specialFunc(float x) const =0;
};
class Specialized_one : public Generic
{
private:
virtual float specialFunc(float x) const{ return x;}
};
class Specialized_two : public Generic
{
private:
virtual float specialFunc(float x) const{ return 2*x; }
}
Run Code Online (Sandbox Code Playgroud)
因此我想我必须使用a std::vector<Generic*>
,并动态创建和销毁对象.
一位朋友建议我std::function<>
为我的Generic
类使用一个属性,并将其specialFunc
作为参数提供给构造函数,但我不确定如何正确地执行它.
这两种方法的优点和缺点是什么,还有其他(更好的)方法来做同样的事情吗?我很好奇.
有关详细信息,我实例化的每个对象的特化将在运行时确定,具体取决于用户输入.我可能最终会得到很多这些对象(还不确定有多少),所以我想避免任何不必要的开销.
首先,让我们把性能抛到九霄云外。
如果您使用virtual
函数,正如您所说,您最终可能会得到许多具有相同接口的类:
class generic {
virtual f(float x);
};
class spec1 : public generic {
virtual f(float x);
};
class spec2 : public generic {
virtual f(float x);
};
Run Code Online (Sandbox Code Playgroud)
作为会员使用std::function<void(float)>
可以让您避免所有专业化:
class meaningful_class_name {
std::function<void(float)> f;
public:
meaningful_class_name(std::function<void(float)> const& p_f) : f(p_f) {}
};
Run Code Online (Sandbox Code Playgroud)
事实上,如果这是您使用该类的唯一用途,您不妨删除它,并std::function<void(float)>
在调用者级别使用 a 。
优点std::function
:
1)更少的代码(N个函数需要1个类,而虚拟方法需要N个函数的N个类。我假设这个函数是类之间唯一不同的东西)。
2) 更加灵活(如果需要,您可以传入捕获保存状态的 lambda)。
3)如果将类编写为模板,则可以根据需要将其用于各种函数签名。
使用std::function
可以解决您尝试使用virtual
函数解决的任何问题,而且它似乎做得更好。但是,我不会断言这std::function
总是比几个类中的一堆虚拟函数更好。有时,这些函数必须是私有的和虚拟的,因为它们的实现与任何外部调用者无关,因此灵活性并不是一个优势。
缺点std::function
:
1)我正要写你不能访问类的私有成员generic
,但后来我意识到你可以使用std::function
捕获 lambda 来修改类本身中的this
。然而,考虑到您概述该类的方式,这应该不是问题,因为它似乎忽略了任何类型的内部状态。