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

标签 c++ coding-style

我有一个名为 GeneticOperator 的类,它负责遗传程序中的变异和交叉运算符。我对不同的突变有不同的函数,对突变有一个公共(public)函数,其中我有类型的 switch 语句。在函数 random() 中,我对突变类型和染色体中要突变的基因数量进行随机选择。

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;
}

functionMutation()argumentsMutation() 看起来像复制粘贴编程。

如何避免?我试图在这个函数中只返回 GenePtr,但是方法 mutation() 并不清楚。

你有什么建议?

最佳答案

复制粘贴的方法实际上只是堆满了不必要的代码。我消除重复的解决方案是添加一个函数以从父基因中获取随机功能基因。这也将阐明函数的目的。

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();
}

我希望我没有误解代码,但有时很难猜出发生了什么。

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

关于c++ - 有时允许复制粘贴编程吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35808420/

相关文章:

c++ - 循环和数组

java - 你把 super() 调用放在构造函数的开头吗?

coding-style - 什么时候违反单一职责原则是合理的?

java - 在一个方法中用大括号分隔代码段是不好的做法吗?

c - 动态内存分配的流行用法

C++ get 和 typecasting 的用法区别是什么?我应该使用哪一个?

c++ - GCC __attribute__ 在 32 字节处对齐的 AVX 向量化代码中的段错误

android - idea文件夹的codeStyles中的codeStyleConfig xml文件是什么?

c++ - 如何从 Qt 中的文件加载图像?

c++ - 使用 vcxproj 重用代码不起作用