超负荷操作员身体的奥秘

The mysteries of an overloaded operator's body

本文关键字:奥秘 操作员 超负荷      更新时间:2023-10-16

假设我有以下类:

树木

和树木;

对象树包含树对象的数组。

以下是树和树类的内容:

树.h:

#pragma once
#include "Tree.h"
class Trees
{
private:
    Tree m_Tree[20];
    int iTrees;
public:
    Trees(void) : iTrees(0){}
    Tree GetTree(int i){ return m_Tree[i];}
    void AddTree(Tree tree){ m_Tree[iTrees++] = tree;}
};

树:

#pragma once
#include <string>
class Tree
{
private:
    std::string Name;
    bool HasRelatives;
public:
    Tree(void):HasRelatives(0){};
    Tree(std::string name):Name(name), HasRelatives(0){};

    std::string GetName(){ return Name;}
    void SetName(std::string name){ Name = name;}
    bool GetHasRelatives(){ return HasRelatives;}
    void SetHasRelatives(bool alone){ HasRelatives = alone;}

    bool operator == (Tree & tree)
    {
        if(this->GetName() == tree.GetName())
        {
            this->SetHasRelatives(1);
            tree.SetHasRelatives(1);
            return 1;
        }
        return 0;
    }
};

假设我正在使用这样的类(main.cpp):

#include <iostream>
#include "Trees.h"

int main()
{
    Trees Trees;
    Trees.AddTree(Tree("Oak"));
    Trees.AddTree(Tree("Oak"));

    if(Trees.GetTree(0) == Trees.GetTree(1))
    {
        std::cout<<"Trees are the same" << std::endl;
        if(Trees.GetTree(1).GetHasRelatives() == 1)
            std::cout<<"Tree has relatives" << std::endl;
    }
    return 0;
}

根据我目前的理解,程序应该输出"树有亲戚",因为第二个树(Trees.GetTree(1))是通过引用传递的,因此在 == 运算符主体内所做的任何更改都应该在它外面可见......

我错在哪里?

虽然operator==改变其参数的语义是值得怀疑的,但您的具体问题是您从GetTree返回副本:

Tree GetTree(int i){ return m_Tree[i];}

因此,当您应用==时,副本会被修改,然后它们被丢弃。当您再次调用GetTree时,新副本当然不会被修改。

你需要的是

Tree& GetTree(int i){ return m_Tree[i];}

以便能够修改存储在m_Tree[i]中的树。