放置操作员功能的一致性

时间:2010-06-14 06:33:07

标签: c++ class operators consistency

我有一个这样的课程:

class A {
    ...private functions, variables, etc...
public:
    ...some public functions and variables...

    A operator * (double);
    A operator / (double);
    A operator * (A);
    ...and lots of other operators
}

但是,我希望能够执行2 * A之类的内容,而不仅仅是允许执行A * 2,所以我需要在课堂外使用这些函数:

A operator * (double, A);
A operator / (double, A);
...etc...

我是否应该将所有这些操作员放在课堂之外以保持一致性,还是应该将一半放在一半内外?

3 个答案:

答案 0 :(得分:2)

恕我直言,关注的不应该是风格的一致性,而是封装的一致性;通常,如果函数不需要访问私有成员,则它不应该是类的一部分。这不是一个很难的快速规则,请参阅它的参数here

因此,如果您的运营商不需要私人访问,请将它们全部放在外面。否则,他们都必须像这样:

class A {
    ...
public:
    ...
    A operator * (double);
    A operator / (double);
    friend A operator * (double, A);
    friend A operator / (double, A);
    ...
};

答案 1 :(得分:2)

从您对问题中的评论的回复中,您似乎已经在班级中从double隐式转换为A。类似的东西:

class A
{
    // ...
public:
    A(double);

    // ...
};

在这种情况下,您只需为表单的每个运算符定义一个自由函数:

A operator*( const A&, const A& );

如果任何一方是A对象而另一方可以隐式转换为A,则会使用它。由于这个原因,通常最好使对称二元运算符自由函数。

根据分配版本*,通常可以更轻松地实现二进制*=。在这种情况下,我会将赋值版本作为成员函数,并将*定义为:

A operator*( const A& l, const A& r )
{
    A result(l);
    result += r;
    return result;
}

否则,operator*显然属于您的类界面,如果需要,我可以将其设为friend

答案 2 :(得分:1)

所以你要说的是因为你必须把一些操作员(那些没有A的操作员作为第一个参数)放在课外,也许你应该把它们放在那里所以人们知道去哪里找到他们?我不这么认为。我希望尽可能在课堂上找到操作员。当然把“外部”的文件放在同一个文件中,这会有所帮助。如果外部的人需要访问私有成员变量,那么添加friend行是一个巨大的提示,可以在文件的其他位置查找这些运算符。

即使我的实施操作符实际上可以通过公共getter和setter完成,我是否会包含friend行?我想我会的。我认为这些运营商确实是班级的一部分。只是语言语法要求它们是自由函数。所以我通常使用friend并将它们写成成员函数,而不是使用getter和setter。这是一个令人愉快的副作用,因此对friend语句的最终需求将导致它们全部列在类的定义中。