C++ 有时允许复制粘贴编程吗?

C++ 有时允许复制粘贴编程吗?,c++,coding-style,C++,Coding Style,我有一个名为geneticcoperator的类,负责遗传程序中的变异和交叉算子。对于不同的变异我有不同的函数,对于变异我有一个公共函数,其中对于类型我有switch语句。在函数中,random()I列出染色体中要突变的基因的突变类型和数量 class GeneticOperator { public: enum MutationType { FUNCTION_MUTATION, ARGUMENTS_MUTATION, WORSTG

我有一个名为
geneticcoperator
的类,负责遗传程序中的变异和交叉算子。对于不同的变异我有不同的函数,对于变异我有一个公共函数,其中对于类型我有switch语句。在函数中,
random()
I列出染色体中要突变的基因的突变类型和数量

class GeneticOperator
{
public:
    enum MutationType
    {
        FUNCTION_MUTATION,
        ARGUMENTS_MUTATION,
        WORSTGENES_MUTATION //not implemented yet
    };
    enum CrossoverType //not implemented yet
    {
        ONEPOINT_CROSSOVER,
        TWOPOINT_CROSSOVER,
        UNIFORM_CROSSOVER,
        BESTGENE_CROSSOVER
    };
public:
    GeneticOperator();
    //GeneticOperator(const GeneGenerator* geneGenerator,
    //                int maxNGene);


    ChromosomePtr mutation(const Chromosome& parent) const;

private:
    void random();

    ChromosomePtr functionMutation(const Chromosome& parent) const;
    ChromosomePtr argumentsMutation(const Chromosome& parent) const;
private:
    const GeneGenerator* geneGenerator_;
    MutationType mutationType_;
    CrossoverType crossoverType_;
    int nMutatedGene_;
    int maxNMutatedGene_;
};
职能:

ChromosomePtr GeneticOperator::mutation(const Chromosome &parent) const
{
    if (parent.getSize() < maxNMutatedGene_)
    {
        throw "Za malo genow w chromosomie";
    }
    this->random();
    switch(mutationType_)
    {
    case FUNCTION_MUTATION:
        return functionMutation(parent);

    case ARGUMENTS_MUTATION:
        return argumentsMutation(parent);

    case WORSTGENES_MUTATION:
        //not implemented yet
        break;

    default:
        throw "Bad enum type";
        break;
    }
    return nullptr;
}

ChromosomePtr GeneticOperator::functionMutation(const Chromosome &parent) const
{
    ChromosomePtr child = parent.copy();

    for(int i = 0; i < nMutatedGene_; i++)
    {
        GenePtr newGene = nullptr;
        int geneNumber = rand() % (parent.getSize() - 1);

        switch(parent.getGene(geneNumber)->getType())
        {
        case Gene::TERMINAL_GENE:
            i--;
            break;

        case Gene::FUNCTION_GENE:
            int nArguments = parent.getGene(geneNumber)->getNArguments();
            GenePtr randomGene = move(geneGenerator_->getRandomFunctionGene(nArguments));
            for(int k = 0; k < nArguments; k++)
            {
                randomGene->addChild(parent.getGene(geneNumber)->getChild(k));
            }
            break;
        }
    }

    return child;
}

ChromosomePtr GeneticOperator::argumentsMutation(const Chromosome& parent) const
{
    ChromosomePtr child = parent.copy();

    for(int i = 0; i < nMutatedGene_; i++)
    {
        GenePtr newGene = nullptr;
        int geneNumber = rand() % (parent.getSize() - 1);

        switch(parent.getGene(geneNumber)->getType())
        {
        case Gene::TERMINAL_GENE:
            i--;
            break;

        case Gene::FUNCTION_GENE:
            GenePtr randomGene = move(parent.getGene(geneNumber)->clone());
            int nArguments = parent.getGene(geneNumber)->getNArguments();
            for(int k = 0; k < nArguments; k++)
            {
                int childGeneNumber = rand() % geneNumber;
                randomGene->setChild(childGeneNumber, k);
            }
            break;
        }
    }

    return child;
}
ChromosomePtr GeneticOperator::突变(常量染色体和父染色体)常量
{
if(parent.getSize()随机();
开关(突变型)
{
病例功能变异:
返回函数(父级);
病例参数和突变:
返回参数(父级);
病例WORSTGENES_突变:
//尚未实施
打破
违约:
抛出“坏枚举类型”;
打破
}
返回空ptr;
}
染色体PTR GeneticOperator::函数突变(常量染色体和父染色体)常量
{
ChromosomePtr child=parent.copy();
对于(int i=0;igetType()
{
病例基因::末端基因:
我--;
打破
病例基因::功能基因:
int nArguments=parent.getGene(geneNumber)->getNArguments();
GenePtr randomGene=move(geneGenerator->getRandomFunctionGene(nArguments));
for(int k=0;kaddChild(parent.getGene(geneNumber)->getChild(k));
}
打破
}
}
返回儿童;
}
染色体PTR GeneticOperator::ArgumentsStation(常量染色体和父染色体)常量
{
ChromosomePtr child=parent.copy();
对于(int i=0;igetType()
{
病例基因::末端基因:
我--;
打破
病例基因::功能基因:
GenePtr randomGene=move(parent.getGene(geneNumber)->clone());
int nArguments=parent.getGene(geneNumber)->getNArguments();
for(int k=0;ksetChild(childGeneNumber,k);
}
打破
}
}
返回儿童;
}
functionMutation()
argumentsStation()
看起来像复制粘贴编程

我怎样才能避免呢?我试图在这个函数中只返回
GenePtr
,但是方法
mutation()
不清楚


你有什么建议?

至于你的问题的标题

有时允许复制粘贴编程吗? 不,是骨头上的错音1(嘿,这首歌押韵)

我怎样才能避免呢

避免复制/粘贴实现的通常方法是提供模板函数或类,这些模板函数或类会排除类型不特定的代码

特定类型的代码可以重构为特定类型的函数调用


1) 静态代码分析工具甚至做出了大量的努力来检测复制/复制修改的代码,并警告复制过程中可能出现的错误。
用最少的误报来检测这一点的真正好的工具是相当昂贵的,所以不要这样做

ChromosomePtr GeneticOperator::突变(常量染色体和父染色体,字符串类型)常量
{
ChromosomePtr child=parent.copy();
对于(int i=0;igetType()
{
病例基因::末端基因:
我--;
打破
病例基因::功能基因:
如果(类型=“函数”){
M(家长);
}else if(类型==“参数”){
M(父母);
}
打破
}
}
返回儿童;
}

复制粘贴的方法实际上只是被不必要的代码弄得乱七八糟。我消除重复的方法是添加一个函数,从父基因中获得一个随机函数基因。这也将澄清职能的目的

GenePtr GeneticOperator::getRandomFuncGene(const Chromosome &parent) const
{
    while(true)
    {
        int geneNumber = rand() % (parent.getSize() - 1);
        if (parent.getGene(geneNumber)->getType()) 
        {
            return parent.getGene(geneNumber);
        }
    }
}
使用新方法并在消除杂波后,旧函数如下所示:

ChromosomePtr GeneticOperator::functionMutation(const Chromosome &parent) const
{
    for(int i = 0; i < nMutatedGene_; i++)
    {
        GenePtr funcGene = getRandomFuncGene(parent);

        int nArguments = funcGene->getNArguments();
        GenePtr randomGene = move(geneGenerator_->getRandomFunctionGene(nArguments));
        for(int k = 0; k < nArguments; k++)
        {
            randomGene->addChild(funcGene->getChild(k));
        }
    }

    return parent.copy();
}

ChromosomePtr GeneticOperator::argumentsMutation(const Chromosome& parent) const
{
    for(int i = 0; i < nMutatedGene_; i++)
    {
        GenePtr funcGene = getRandomFuncGene(parent);

        GenePtr randomGene = move(funcGene->clone());
        int nArguments = funcGene->getNArguments();
        for(int k = 0; k < nArguments; k++)
        {
            int childGeneNumber = rand() % geneNumber;
            randomGene->setChild(childGeneNumber, k);
        }
    }

    return parent.copy();
}
ChromosomePtr GeneticOperator::functionMutation(常量染色体和父染色体)常量
{
对于(int i=0;igetNArguments();
GenePtr randomGene=move(geneGenerator->getRandomFunctionGene(nArguments));
for(int k=0;kaddChild(funcGene->getChild(k));
}
}
返回parent.copy();
}
染色体PTR GeneticOperator::ArgumentsStation(常量染色体和父染色体)常量
{
对于(int i=0;iclone());
int nArguments=funcGene->getNArguments();
for(int k=0;ksetChild(childGeneNumber,k);
}
}
返回parent.copy();
}
我希望我没有误解代码,但有时很难猜出发生了什么


这些函数还存在一些其他问题。据我所知,返回值与函数的实际用途不符。

如果它们执行的是完全相同的操作,请使用一个函数调用另一个函数。如果他们有一些共同的部分,把共同的部分放在
ChromosomePtr GeneticOperator::functionMutation(const Chromosome &parent) const
{
    for(int i = 0; i < nMutatedGene_; i++)
    {
        GenePtr funcGene = getRandomFuncGene(parent);

        int nArguments = funcGene->getNArguments();
        GenePtr randomGene = move(geneGenerator_->getRandomFunctionGene(nArguments));
        for(int k = 0; k < nArguments; k++)
        {
            randomGene->addChild(funcGene->getChild(k));
        }
    }

    return parent.copy();
}

ChromosomePtr GeneticOperator::argumentsMutation(const Chromosome& parent) const
{
    for(int i = 0; i < nMutatedGene_; i++)
    {
        GenePtr funcGene = getRandomFuncGene(parent);

        GenePtr randomGene = move(funcGene->clone());
        int nArguments = funcGene->getNArguments();
        for(int k = 0; k < nArguments; k++)
        {
            int childGeneNumber = rand() % geneNumber;
            randomGene->setChild(childGeneNumber, k);
        }
    }

    return parent.copy();
}