我有一个这样的课程:
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...
我是否应该将所有这些操作员放在课堂之外以保持一致性,还是应该将一半放在一半内外?
答案 0 :(得分:2)
因此,如果您的运营商不需要私人访问,请将它们全部放在外面。否则,他们都必须像这样:
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
语句的最终需求将导致它们全部列在类的定义中。