如何避免代码重复或多次迭代

How to avoid code duplication or multiple iterations?

本文关键字:迭代 何避免 代码      更新时间:2023-10-16

考虑以下代码:

struct Person{
enum sex{male,female};
int salary;
};
struct PersonSSN:public Person{
int ssn;
};

我有一个容器,其中只包含Person或PersonSSN,(在编译时已知)按工资值升序排序。我必须写一个函数myfunc(),它做以下事情。

void myfunc(){
if the container contains Person:
      print the number of females between two consecutive males.
else if the container contains PersonSSN: 
      print the number of females between two consecutive males 
      and 
      the ssn of the males.
}

对于这个问题,我有两个解决方案,但都有一些缺点。

解决方案1:如果我写一个函数打印男性和女性之间的数量,另一个函数打印性别,我必须遍历数据两次,这是昂贵的。

解决方案2:我可以写两个类,MyfuncMyfuncSSN衍生自Myfunc,并有一个虚函数process()。但是,打印女性数量的代码段必须从Myfunc类的process()方法复制到MyfuncSSN类中。这里没有代码重用。

什么是更好的解决方案?

如果您谈论的是编译时的对象识别,那么答案可能只有一个-模板。根据您使用的容器类型,它会有所不同,但如果您使用std::list,它将是

#include <list>
template <typename T>
void myfunc(std::list<T>);
template <>
void myfunc(std::list<Person> lst){
    print the number of females between two consecutive males.
}
template <>
void myfunc(std::list<PersonSSN> lst){
    print the number of females between two consecutive males 
    and 
    the ssn of the males.
}
编辑:

如果你想提交双迭代,我唯一能想到的就是使用单个模板函数来迭代和打印两个连续的男性之间的女性数量,调用另一个模板函数来打印SSN:

#include <list>
template <typename T>
void printperson(T p){}
template <>
void printperson(Person p){
    // Do nothing - perhaps you might skip it and use generic implementation instead
}
template <>
void printperson(PersonSSN p){
    print ssn of the person p if it is male.
}
template <typename T>
void myfunc(std::list<T>){
    print the number of females between two consecutive males.
    and while doing so call printperson(list_element);
}

这可能适用于这个简单的示例,但我确信,对于更复杂的示例—假设您想要为PersonSSN打印女性之间的额外数量的男性—它可能会出现不足,因为这两个操作(虽然相似)可能会被证明是不可能分离成不同类型的功能部分。然后,它将需要代码加倍或两次迭代-不要认为有其他方法可以绕过它。

注意:你可以(如注释中建议的)在function-args中切换到const-references -我更习惯使用隐式共享的qt容器,因此不需要它

这个例子在很多不同的层面上都是错误的:)

理想情况下,"Person"应该是一个类;"name"、"sex"answers"SSN"都是基类的成员,"process()"要么是方法(),要么是虚方法()。

问:是否有可能将Person和PersonSSN更改为类,并使"process()"成为方法?

问:你的程序如何"知道"它是有"Person"记录还是"PersonSSN"记录?你能把它作为"process()"函数的一个参数吗?

附录9.16.2011 :

这个问题是"你的代码如何区分‘Person’和‘PersonSSN’?"

如果您使用一个类,您可以使用"typeof"(不满意),或者您可以将特定于类的行为绑定到类方法(首选,并且建议使用"模板"建议)。

您还需要至少三个不同的类:"Person"类(其外观和行为都像一个人),"PersonSSN"类(具有额外的数据和可能的额外行为)…还有一个"优步班",知道如何计算人名和人名。

所以,是的,我建议应该有一些类,或者使用"Persons"answers"personssn"。

是的,你可以考虑你的代码,一个类使用" process -count-连续",另一个调用父类" process -count-连续",并添加一个新的"print ssn"。