我正在为遗传算法/神经进化编写一个库。目前,该程序使用多态性来允许多种类型的基因组。所以我的代码看起来像这样:
class Genome { // Interface
// Some abstract functions
}
class SpecificGenome : public Genome {
// implementation
public:
int do_something(int x); // Specific behavior, which only this SpecificGenome has
}
class Population {
public:
Population(size_t population_size, std::function<std::unique_ptr<Genome>()> create_genome);
// Some functions
std::vector<std::unique_ptr<Genome>> members;
}
std::unique_ptr<Genome> create_specific_genome(){
return std::unique_ptr<Genome>(std::make_unique<SpecificGenome>());
}
int main() {
Population p(150, &create_specific_genome);
int y = static_cast<SpecificGenome>(*p.members[0].get())->do_something(4);
}
我正在考虑对其进行更改,以便它使用模板而不是多态性,因为每个基因组都编码一个现象组,该现象组可以具有任何类型的行为并且与其他现象组类型没有任何共同点,并且一些基因组使用直接编码方案,不必解码为现象。因此,每个基因组都必须由用户转换为相应的子类,以暴露其行为,这看起来非常丑陋。 问题是基因组的每个子类都是基因组并且需要有一些特定的功能才能工作,因此多态性非常有意义。
编辑: 现在的问题很不清楚,所以我想补充一些额外的解释。我希望能够创建具有任何类型基因组(神经网络、NEAT 基因组、图像等)的种群,所以我使用接口(interface)和子类来完成此操作,以便种群中的 vector 可以使用基因组指针。这很有用,因为每个基因组类型都需要有特定的方法,如交叉和变异。问题出现了,当我想使用特定的函数,比如计算神经网络的输出、基因组解码或获取图像的像素数据时,基因组解码。这让我怀疑使用模板而不是继承是否会更好。
最佳答案
模板可能会更好地帮助您解决问题,但还有其他含义。
例如,您的列表在其包含的基因组类型中不能是异质的。它必须都是同一类型。如果您需要异质性,则必须实现某种类型删除。
这是一个看起来像您的示例但具有静态多态性的示例:
// no inheritance
class SpecificGenome {
public:
int do_something(int x);
}
template<typename G, typename C>
class Population {
public:
Population(size_t population_size, C create_genome);
// no need for pointers. Values work just fine.
std::vector<G> members;
}
// Deduction guide using the create_genome function return type
template<typename C>
Population(std::size_t, C) -> Population<std::invoke_result_t<C>, C>;
SpecificGenome create_specific_genome() {
return SpecificGenome{};
}
int main() {
// Uses class template argument deduction
Population p(150, create_specific_genome);
int y = p.members[0].do_something(4);
}
顺便说一下,如果您仍然使用 std::unique_ptr
,您可以使用更好的语法来使用它:
std::unique_ptr<Genome> create_specific_genome() {
// no need for casts
return std::make_unique<SpecificGenome>();
}
// no need for calls to `get`.
int y = static_cast<SpecificGenome&>(*p.members[0]).do_something(4);
关于c++ - 模板与多态性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56008187/