C++ 为重建重载运算符()是一种好的做法吗?

C++ 为重建重载运算符()是一种好的做法吗?,c++,operator-overloading,C++,Operator Overloading,我想到了以下情景: class A { private: std::string id; std::array<std::string, 128> data; public: A(const std::string& id) : id(id) {} A(const A& other) : id(other.id), data(other.data) {} virtual ~A(){} //to o

我想到了以下情景:

class A {
    private:

    std::string id;
    std::array<std::string, 128> data;

    public:

    A(const std::string& id) : id(id) {}
    A(const A& other) : id(other.id), data(other.data) {}
    virtual ~A(){}

    //to override the intern data
    A& operator=(const A& other) {

        this->data = other.data;

        return *this;
    }

    //to override the whole element
    A& operator()(const A& other) {

        this->id = other.id;
        this->data = other.data;

        return *this;
    }
};
A类{
私人:
std::字符串id;
std::数组数据;
公众:
A(const std::string&id):id(id){}
A(const A&other):id(other.id),data(other.data){}
虚拟~A(){}
//覆盖实习生数据的步骤
A运算符=(常量A和其他){
此->数据=其他.data;
归还*这个;
}
//覆盖整个元素
运算符()(常量A和其他){
此->id=other.id;
此->数据=其他.data;
归还*这个;
}
};
如您所见,我的想法是使用operator=覆盖内部数据,使用operator()覆盖整个元素。我受到了构造函数的启发,它允许
A(anOtherA)
来构造元素,我想重写它以进行重新构造。现在我不知道这是否是智能重载,因为它实际上是函数调用操作符

为重建重载运算符()是一种好的做法吗? 简言之,不,这不是好的做法。这样做只是混淆了引擎盖下的工作

数据提供setter
并使用重载的
操作符()
中提供的代码来实现赋值
操作符=()
将提供更清晰、自然的语义:

class A {
    private:

    std::string id;
    std::array<std::string, 128> data;

    public:

    A(const std::string& id) : id(id) {}
    A(const A& other) : id(other.id), data(other.data) {}
    ~A(){}

    //to override the intern data
    A& operator=(const A& other) {
        id = other.id;
        data = other.data;

        return *this;
    }

    //to override the intern data
    void setData(const A& other) {
         data = other.data;
    }
    void setData(const std::array<std::string, 128>& data_) {
         data = data_;
    }
};

πάντα给出了很好的答案ῥεῖ 所以请投那个答案,而不是这个

当你写的时候,更重要的是,多读C++,你会认识到用自然、有意义的名字来命名方法和功能的人。

对于我们大多数人来说,如果我们看到这样的代码:

X x;
Y y;

x(y);
我们甚至会认为,在看
X
Y
的声明之前,
X
是某种函数对象(即它做了些什么),而
Y
是某种数据或状态对象-它喜欢对它做一些事情,或者它提供数据或服务

作为旁注,Haskell程序员自然会认为
Y
也是一个函数,但这是另一回事

如果您的
X::operator()(Y)
的实现没有“使用Y或对Y执行X-type操作”,那么它的命名可能不恰当

如果
Y
实际上表示
X
的新状态,并且
X
打算使用
Y
中的数据“重置”自身,则该方法可能应被调用<代码>重置:

X x;
Y y;

x.reset(y);  //ok, this is telling a better story
使用合理的名称,我们可以用代码讲述故事:

void processResults(XFactory& factory, std::istream& is) {
    while(is) {
        auto x = X::createFrom(factory);
        x.collectNResults(is, 10);
        auto a = x.takeAverage();
        storeAverage(a);
        x.reset(y);
    }
}
现在,即使不查阅各种类别的定义,我也能理解一般的叙述。这对眼睛来说更容易,而且我将能够更快速地了解我需要的信息,而不是:

void processResults(XFactory& factory, std::istream& is) {
    while(is) {
        auto x = X(factory);
        x(is, 10);
        auto a = x();
        x(averageStore);
        x(y);
    }
}

如果我把X上的每一个操作都写成呼叫接线员的话,我会得到这个结果,就像公司避税一样,实际上是完全合法的,但是,这也会让其他人感到不安,因为他们最终会为你的自私付出代价。< > P>函数,你可以把函数命名为“你想使语义清晰”,但是<>代码>覆盖> <代码>是C++的关键工作,所以要小心。我有点忘了,别问那是怎么发生的。。。我将使用另一个名称实际上,
override
是一个上下文敏感的关键字。您可以将其用作标识符。@BenjaminLindley啊,谢谢您提供的信息。我还在学习:)好吧,在这种情况下,我可能会使用override();)谢谢你information@Richard“请把那个答案投上一票,而不是这个。”这太体面了,请投上一票;P.@πνταῥεῖ 啊,你太好了。
void processResults(XFactory& factory, std::istream& is) {
    while(is) {
        auto x = X(factory);
        x(is, 10);
        auto a = x();
        x(averageStore);
        x(y);
    }
}