深度复制结构

时间:2011-03-01 01:35:29

标签: c++ struct

我的struct定义如下

struct VariableList
{
    void Add(simple_instr* instr)
    {
        //PrintOpcode(instr);
        switch(instr->opcode)
            {
                case STR_OP:
                case MCPY_OP:
                    Add(instr->u.base.src1);
                    Add(instr->u.base.src2);
                    break;  

                case LDC_OP: 
                    Add(instr->u.ldc.dst);
                    break;  

                case BTRUE_OP:
                case BFALSE_OP: 
                    Add(instr->u.bj.src);
                    break;              

                case CALL_OP:
                    if (instr->u.call.dst != NO_REGISTER)
                    {
                        Add(instr->u.call.dst);
                    }

                    Add(instr->u.call.proc);

                    for (int i = 0; i < instr->u.call.nargs; i++)
                    {
                        Add(instr->u.call.args[i]);
                    }

                    break;

                case MBR_OP:                    
                    Add(instr->u.mbr.src);
                    break;          

                case RET_OP:
                    if (instr->u.base.src1 != NO_REGISTER)
                        Add(instr->u.base.src1);
                    break;              

                case CVT_OP:
                case CPY_OP:
                case NEG_OP:
                case NOT_OP: 
                case LOAD_OP: 
                    Add(instr->u.base.dst);
                    Add(instr->u.base.src1);
                    break;

                case LABEL_OP:
                case JMP_OP:
                    break;                      

                default:
                    Add(instr->u.base.dst);
                    Add(instr->u.base.src1);
                    Add(instr->u.base.src2);
                    break;

            }
    }

    void Add(Variable var)
    {
        variableList.push_back(var);
    }

    void RemoveDuplicates()
    {
        if (variableList.size() > 0)
        {
            variableList.erase(unique(variableList.begin(), variableList.end()), variableList.end());
            currentID = variableList.size();
        }
    }

    VariableList()
    {
        currentID = 0;
        dynamicallyCreated = false;
    }

    VariableList(VariableList& varList, bool setLiveness = false, bool LiveVal = false)
    {
        currentID = 0;
        for (int i = 0; i < varList.size(); i++)
        {
            Variable* var = new Variable(varList[i]);
            if (setLiveness)
            {
                var->isLive = LiveVal;
            }

            variableList.push_back(*var);
        }

        dynamicallyCreated = variableList.size() > 0;
    }

    Variable& operator[] (int i)
    {
        return variableList[i];
    }

    int size()
    {
        return variableList.size();
    }

    vector<Variable>::iterator begin()
    {
        return variableList.begin();
    }

    vector<Variable>::iterator end()
    {
        return variableList.end();
    }

    bool CompareLiveness(VariableList &var)
    {
        if(variableList.size() != var.size())
        {
            return false;
        }

        for (int i = 0; i < variableList.size(); i++)
        {
            if(variableList[i].isLive != var[i].isLive)
                return false;
        }
        return true;
    }

    ~VariableList()
    {
        if(dynamicallyCreated)
        {
            for (vector<Variable>::iterator it = variableList.begin(); it < variableList.end(); ++it)
            {
                //delete (&it);
            }
        }
    }

    protected:
        int currentID;
        vector<Variable> variableList;
        bool dynamicallyCreated;
        void Add(simple_reg* reg, bool checkForDuplicates = false)
        {   
            if (reg == null)
            {
                cout << "null detected" << endl;
                return;
            }

            if (reg->kind == PSEUDO_REG)
            {                       
                if (!checkForDuplicates || (checkForDuplicates && find(variableList.begin(), variableList.end(), reg->num) != variableList.end()))
                {
                    cout << "Adding... Reg  " << reg->num << endl;
                    Variable* var = new Variable(reg->num, currentID);              
                    variableList.push_back(*var);
                    currentID++;
                }
            }
        }
};

我希望能够做出像这样的声明

VariableList varsIn(Variables, true, false);

将创建一个深层副本,并允许我更改一些属性。正如您在我的结构中所看到的,我目前正在尝试使用

执行此操作
VariableList(VariableList& varList, bool setLiveness = false, bool LiveVal = false)
{
    currentID = 0;
    for (int i = 0; i < varList.size(); i++)
    {
        Variable* var = new Variable(varList[i]);
        if (setLiveness)
        {
            var->isLive = LiveVal;
        }

        variableList.push_back(*var);
     }

     dynamicallyCreated = variableList.size() > 0;
}

我认为这不是正确的做法。这种复制的正确方法是什么?有没有办法不使用新的?作为参考,Variable结构如下

struct Variable
{
    int id;
    int num;
    bool isLive;
    simple_op opcode;

    Variable()
    {
        id = 0;
    num = 0;
    opcode = NOP_OP;
    vClass = Basic;
    isLive = false;
    }

    Variable(int _num, int _id = 0, simple_op _op = NOP_OP)
    {
        id = _id;
    num = _num;
    opcode = _op;
    vClass = Basic;
    isLive = false;
    }

    VariableClass GetClass()
    {
        return vClass;
    }

    bool operator==(const Variable &var) const 
    {
        return num == var.num;
    }

    bool operator==(const int &x) const
    {
    return x == num;
    }

    protected:
        VariableClass vClass;
};

VariableClasssimple_op是枚举

提前致谢

1 个答案:

答案 0 :(得分:2)

您的代码不仅不必要地进行动态分配,而且还在各处泄漏Variable个实例。只需使用自动变量,push_back即可复制:

VariableList(VariableList& varList, bool setLiveness = false, bool LiveVal = false)
{
    currentID = 0;
    for (int i = 0; i < varList.size(); i++)
    {
        Variable var(varList[i]);
        if (setLiveness)
        {
            var.isLive = LiveVal;
        }

        variableList.push_back(var);
     }
}

取出析构函数,你不能删除向量所拥有的元素。如果他们指向某处,当然,但你没有存储指针。

此外,这是一个更好的方法:

VariableList(VariableList& other, bool setLiveness = false, bool LiveVal = false)
    : currentID(0)
    , variableList(other.variableList)
{
    if (setLiveness) {
        for( int i = 0; i < size(); i++ )
            variableList[i].isLive = LiveVal;
    }
}