C++ 类间共享函数
我有三个类,每个类存储它们自己的双值数组。为了填充数组,我使用了一个相当复杂的函数,比如说C++ 类间共享函数,c++,oop,C++,Oop,我有三个类,每个类存储它们自己的双值数组。为了填充数组,我使用了一个相当复杂的函数,比如说foo(),它接受多个参数并为数组计算适当的值 我的三个类中的每一个都使用相同的函数,只需稍作调整(即输入参数略有变化)。每个类实际上都非常相似,尽管它们在检索数组值时都执行单独的逻辑 所以我想知道我应该如何“共享”函数,以便所有类都可以使用它,而不必复制代码 我正在考虑创建一个基类,其中包含函数foo()和一个虚拟的get()方法。我的三个类可以继承这个基类。或者,我也在想,也许一个全球性的功能才是出路?
foo()
,它接受多个参数并为数组计算适当的值
我的三个类中的每一个都使用相同的函数,只需稍作调整(即输入参数略有变化)。每个类实际上都非常相似,尽管它们在检索数组值时都执行单独的逻辑
所以我想知道我应该如何“共享”函数,以便所有类都可以使用它,而不必复制代码
我正在考虑创建一个基类,其中包含函数
foo()
和一个虚拟的get()
方法。我的三个类可以继承这个基类。或者,我也在想,也许一个全球性的功能才是出路?如果类的基础数据相同(双精度数组),可以将函数放入命名空间中,考虑使用单个类并重载构造函数,或者只使用3个不同的函数:
无效PopulateFromString(常量字符串&)void PopulateFromXml(…)
void PopulateFromInteger(…) 如果每个类类型中的数据或行为不同,则基类的解决方案是好的
如果函数与特定的类行为(多态性)无关,还可以将与类位于同一命名空间中的函数定义为实用函数。顺便说一句,Bjarne StroupStroup推荐这种方法。在基类中声明函数听起来是最合适的解决方案。但不确定是否需要虚拟“get”,只需在基类中声明数组并为子体提供访问方法即可
更复杂的部分是“输入参数略有变化”。如果参数仅因类型不同而不同,则可以编写模板函数。如果差异比我看到的唯一解决方案更为显著,那就是将主函数拆分为几个逻辑块,并在子类中使用这些块来执行最终结果。如果您的类非常相似,您可以创建一个模板类,其中包含三种不同的实现,它们具有函数
foo()
在基类中实现该函数。如果这些类与您所说的类似,那么它们无论如何都应该派生自一个基类!如果有几个函数,比如foo(),在某些情况下,将它们组合到另一个类中可能是合理的,该类由您的类/与您的类一起使用。为了回答这个问题,我假设您拥有的类在任何其他方面都不常见;它们可以加载相同的数据,但提供不同的接口
这里有两种可能的情况,你还没有告诉我们是哪一种。可能更像
void foo(double* arr, size_t size) {
// Some specific code (that probably just does some preparation)
// Lots of generic code
// ...
// Some more specific code (cleanup?)
}
或者类似于
void foo(double* arr, size_t size) {
// generic_code();
// ...
// specific_code();
// generic_code();
// ...
}
在第一种情况下,泛型代码很容易放入一个单独的函数中,然后创建一个基类没有多大意义:您可能会从它进行私有继承,您应该更喜欢组合而不是私有继承,除非您有充分的理由这样做。如果新函数从中受益,您可以将其放入自己的类中,但严格来说这不是必需的。是否将其放入命名空间取决于您如何组织代码
第二种情况更为棘手,在这种情况下,我建议使用多态性。然而,您似乎不需要运行时多态性,因此您也可以在编译时执行它。利用这是C++的事实,您可以使用CRTP:
template<typename IMPL>
class MyBase {
void foo(double* arr, size_t size) {
// generic code
// ...
double importantResult = IMPL::DoALittleWork(/* args */);
// more generic code
// ...
}
};
class Derived : MyBase<Derived> {
static double DoALittleWork(/* params */) {
// My specific stuff
return result;
}
};
模板
类MyBase{
无效foo(双*arr,大小){
//通用代码
// ...
双重重要性结果=IMPL::DoALittleWork(/*args*/);
//更通用的代码
// ...
}
};
派生类:MyBase{
静态双DOALITLEWORK(/*params*/){
//我的特定物品
返回结果;
}
};
这为您提供了代码组织的好处,并为您节省了一些虚拟函数。另一方面,它确实使需要实现哪些功能变得不那么清楚(尽管如此)
如果生成一个新函数(可能在一个新类中)显然更丑陋,我只会选择第二种方法。如果你像Andrey所说的那样解析不同的格式,那么传入一个解析器对象(可能是多态的)会更好,因为它可以让你不那么麻烦地模拟事情,但是你没有给出足够的细节来确定。如果类除了这个
foo()
函数之外没有任何共同点,把它放在基类中是愚蠢的;让它成为一个自由函数。C++不是java。< /p>尽可能避免全局性。按照您所描述的,用一个基类寻找一个OO解决方案。您所建议的两种方法都是可行的。哪一个更合适在很大程度上取决于我们没有的细节。三个班级之间是否有更多的共同点?如果是这样的话,一个公共基类可能是合适的。foo()是一个有意义的操作,对与当前三个类无关的类可能有用吗?如果是这样,请将其设置为适当命名空间中的全局函数。我建议您在考虑程序的概念时,使用感觉更自然的抽象。这有点含糊不清,但这是编程时需要始终做出的直觉决定。