我有两节课。 Class OnePoint和Class Line。
OnePoint由一个点,两个坐标组成。
一个类线由两个点组成,两个OnePoint对象。
如何添加两个OnePoints以使其成为运算符重载的行?
OnePoint a(3.0, 3.0);
OnePoint b(1.0, 1.0);
Line d;
d = a+b;
cout << d;
变为{(3.0,3.0),(1.0,1.0)}
。
#include <iostream>
using namespace std;
class OnePoint {
private:
double xvalue;
double yvalue;
public:
OnePoint(double x = 0.0, double y = 0.0) {
xvalue = x;
yvalue = y;
}
friend ostream& operator<<(ostream& printh, OnePoint& cPoint) {
printh << "(" << cPoint.xvalue << ',' << cPoint.yvalue << ")";
return printh;
}
void Plus(OnePoint a) {
xvalue = xvalue + a.xvalue;
yvalue = yvalue + a.yvalue;
}
void Minus(OnePoint b) {
xvalue = xvalue + b.xvalue;
yvalue = yvalue + b.yvalue;
}
OnePoint Plustwo(OnePoint a) {
return (xvalue + a.xvalue, yvalue - a.yvalue);
}
void Change(double a, double b) {
xvalue += a;
yvalue += b;
}
void Print(OnePoint b) {
cout << xvalue << "," << yvalue << endl;
}
/*OnePoint operator-(OnePoint a) {
OnePoint temp;
temp.xvalue = xvalue + a.xvalue;
temp.yvalue = yvalue + a.yvalue;
return temp;
}
friend OnePoint operator+(OnePoint a, OnePoint b) {
OnePoint temp;
temp.xvalue = a.xvalue + b.xvalue;
temp.yvalue = a.yvalue + b.yvalue;
return temp;
}*/
};
class Line {
private:
OnePoint onevalue;
OnePoint twovalue;
public:
Line(OnePoint a, OnePoint b) {
onevalue = a;
twovalue = b;
}
/*OnePoint getonevalue() {
return onevalue;
}
OnePoint gettwovalue() {
return twovalue;
}*/
friend ostream& operator<<(ostream& print, Line& cLine){
print << "{"<< cLine.onevalue << ',' << cLine.twovalue << "}";
return print;
}
friend Line operator+(OnePoint a, OnePoint b) {
Line temp; // I have been trying
temp(a, b); //something here without luck
return temp;
}
};
-------------------------------------------------------------------------------
int main(){
OnePoint a(3.0, 3.0);
OnePoint b(1.0, 1.0);
Line d(a, b);
cout << a << endl;
cout << d << endl;
}
答案 0 :(得分:2)
你可以重写(在C ++ 11中)你的operator +
喜欢
Line operator+(const OnePoint& lhs, const OnePoint& rhs)
{
return {lhs, rhs};
}
答案 1 :(得分:1)
所有你需要做的 - 不做任何改变 - 是
OnePoint a(3.0, 3.0);
OnePoint b(1.0, 1.0);
Line d(a,b);
如果你真的想做
d = a + b;
然后您需要提供一个operator+()
,它接受两个类型为OnePoint
的参数,并返回Line
。替代方案是作为OnePoint
// definition of Line here
class OnePoint
{
public:
Line operator+(const OnePoint &) const;
// other member functions, etc
};
Line OnePoint::operator+(const OnePoint &rhs) const
{
Line retval(*this, rhs);
return retval;
}
或作为非会员
// definitions of Line and OnePoint here
Line operator+(const OnePoint &lhs, const OnePoint &rhs); // declaration, not definition
Line operator+(const OnePoint &lhs, const OnePoint &rhs)
{
Line retval(lhs, rhs);
return retval;
}
显然,在上述两种情况下,我都假设operator+()
可以根据需要访问(例如Line
&#39;构造函数)。
请注意,从数学上讲,您所做的是向后的。不使用a+b
语法添加点来获取一条线 - 使用一对点而不是求和来表示线。相反,向量被添加到点以产生其他点。
答案 2 :(得分:0)
你的错误非常微不足道。您的Line类构造函数是多参数构造函数,您需要使用Line
类型的两个参数构造OnePoint
对象。
我已经纠正了你的代码,如果构造函数需要一个或多个参数,你就会知道如何构造类的对象。
friend Line operator+(OnePoint a, OnePoint b) {
Line temp(a,b); // Changed here
return temp;
}
您还可以通过此link了解有关对象构建的基础知识
答案 3 :(得分:0)
请勿覆盖+
来执行此操作。这是非常意外的。
如果您确实需要干净的语法,请使用命名运算符。
这是一个12行named operator library:
namespace named_operator {
template<class D>struct make_operator{make_operator(){}};
template<class T, char, class O> struct half_apply { T&& lhs; };
template<class Lhs, class Op>
half_apply<Lhs, '*', Op> operator*( Lhs&& lhs, make_operator<Op> ) {
return {std::forward<Lhs>(lhs)};
}
template<class Lhs, class Op, class Rhs>
auto operator*( half_apply<Lhs, '*', Op>&& lhs, Rhs&& rhs )
-> decltype( invoke( std::forward<Lhs>(lhs.lhs), Op{}, std::forward<Rhs>(rhs) ) )
{
return invoke( std::forward<Lhs>(lhs.lhs), Op{}, std::forward<Rhs>(rhs) );
}
}
然后我们使用上面的库定义一个实际的命名运算符,如下所示:
struct line_to_tag {}; // tag type
static const named_operator::make_operator<line_to_tag> line_to; // name of operator
// action from operator:
Line invoke( OnePoint lhs, line_to_tag, OnePoint rhs ) {
return Line(lhs, rhs);
}
现在可行:
Point a, b;
Line l = a *lineto* b;
我认为比a+b
更清楚。 (是的,命名运算符库有点令人困惑,但使用点的代码非常清楚)。