2
struct PT 
{   
  double x, y;  
  PT() {}  
  PT(double x, double y) : x(x), y(y) {}  
  PT(const PT &p) : x(p.x), y(p.y)    {}  
  PT operator + (const PT &p)  const { return PT(x+p.x, y+p.y); }  
  PT operator - (const PT &p)  const { return PT(x-p.x, y-p.y); }  
  PT operator * (double c)     const { return PT(x*c,   y*c  ); }  
  PT operator / (double c)     const { return PT(x/c,   y/c  ); }  
};

此代码片段来自http://stanford.edu/~liszt90/acm/notebook.html#file8。我无法理解这段代码。有人请解释一下。我知道这是运算符重载,但无法理解运算符重载是如何发生的。

有人也可以解释这些行:

PT() {}  
PT(double x, double y) : x(x), y(y) {}  
PT(const PT &p) : x(p.x), y(p.y)    {}

结构也有构造函数吗?

4

5 回答 5

2
double x, y;  

声明组成类的两个局部类变量。

PT() {}  

默认构造函数。允许您创建不带任何参数的 PT。
例如 --> PT myObj;

PT(double x, double y) : x(x), y(y) {}  

构造函数从两个双打创建一个点。
例如 --> PT myObj(3.5, 9.0);
在声明之后 --> PT(double x, double y) : x(x), y(y) {}
我们有初始化 .--> PT(double x, double y) : x(x) , y(y) {}
x(x)等价于this->x = x;
即用构造函数参数'x'初始化类变量'x'。他们为参数赋予与类变量相同的名称,这有点令人困惑。一个更好的例子可能是:

    PT(double xInit, double yInit) 
    : x(xInit)
    , y(yInit) 
    {
    }  



    PT(const PT &p) : x(p.x), y(p.y)    {}  

复制构造函数以从另一个 PT 对象创建一个 PT 对象,
例如 --> PT myOtherObj(myObj);

PT operator + (const PT &p)  const { return PT(x+p.x, y+p.y); }  
PT operator - (const PT &p)  const { return PT(x-p.x, y-p.y); }

加法和减法运算符得到两点的总和或差以进行三分之一。
例如 -->

    PT sumObj  = myObj + myOtherObj;
    PT diffObj = myObj - myOtherObj;



PT operator * (double c) const { return PT(x*c, y*c ); }
PT operator / (double c) const { return PT(x/c, y/c ); }

乘法和除法运算符将一个点乘以(或除)一个常数。
例如 -->

    PT prodObj = myObj * 2.7;
    PT divObj  = myObj / 8.0;
于 2012-06-16T06:49:59.180 回答
1

第 4 行和第 5 行是构造函数,语法x(x)突出显示了调用成员变量的构造函数的惯用方式(例如,向下传递)。

请注意,形式参数不需要不同的标识符。从构造函数体内进行赋值需要不同的命名,因为形式参数“隐藏”了成员变量。即我们需要,例如

 PT(double x_, double y_) { x = x_; y = y_; }  

另请注意,这种方式我们不是调用成员 x 的构造函数,而是调用赋值运算符。POD 数据没有区别,但语法允许任意的、用户定义的、类上的成员函数,如PT.

于 2012-06-16T06:32:02.150 回答
0

每当编译器遇到形式的调用

a + b;

它实际上调用

a.operator+(b)

如果此类方法存在于 a 或

operator+(a,b)

如果存在这样的自由功能。

运营商???语法只是说您当前正在重载所述运算符 ??? (对于任何有效的???当然)。

于 2012-06-16T05:56:02.220 回答
0

运算符重载是一个概念,其中像+, '- , '*, ... 这样的常用运算符也对结构/类进行了“重载”。通常,此功能仅适用于原始数据类型,如int, double, ....

在这里struct PT,运算符方法被简单地定义。一旦您声明对象PT并开始使用它,它将启动。例如

PT pt1, pt2;
PT pt3 = pt1 + pt2;  // pt1.operator +() has instantiated
于 2012-06-16T05:56:56.133 回答
0

通过查看它的非成员版本,可能更容易理解运算符重载。如果您想通过添加两个对象来告诉编译器您的意思是什么,PT您可以编写以下内容:

PT operator + (const PT& a, const PT& b)
{
    return PT(a.x + b.x, a.y + b.y);
}

上面的代码只是说,当编译器找到a + b两个ab都是实例的表达式时,结果是该函数计算的PT一个新实例。PT

您可以对其他一些运算符执行相同的操作,并且由于这一点,您可以使您的类实例在正常数学方面表现得更“自然”。

您拥有的代码是相同的,但以某种不自然的不对称形式编写,您可以在其中描述例如将另一个对象添加到this对象时要做什么。这种方法对于二元数学运算符来说看起来很奇怪,因为例如在加法的第一个或第二个操作数中没有什么特别的,而且它们都在同一个逻辑级别上。然而,该概念的不对称性this是 C++ DNA 的一部分,您对此无能为力。从理论上讲,对于任何仅采用参数的方法来说,这都是一种糟糕的不对称性,但实际上,即使使用这种方法,您仍然可以使用很长一段时间。

代码的其他部分是:

// Default constructor. Will create an object without any parameter
// and the x, y values will be uninitialized. This is generally a bad
// practice and you should avoid it unless there are very specific and
// measured performance reasons for doing that.
// Having a constructor accepting no parameters is sometimes necessary
// if you want for example to be able to put your instances in an std::vector
// and you may need to call .resize() on the vector. Even if you will always
// just shrink the vector the compiler will require anyway a default
// constructor because there's no shrink-only call on vectors and any
// resize operation is assumed to be potentially growing the size.
PT() {}

// Copy constructor. This is totally unneeded... when you don't
// put a copy constructor in a class the C++ compiler will automatically
// generate exactly this code (i.e. a constructor that will copy-construct
// all members). In general this may be or may not be the right thing
// depending on the class, but in this case is exactly what you want
// and there was no need for this code.
// As a general rule if you see a copy constructor, an assignment operator
// or a destructor but you don't see all three of them in a class then
// most probably there's something wrong. It's difficult to think to
// a real use case in which you need some of them but not all three of
// them... in this case for example the mistake is that this code could
// and should have been omitted.
PT(const PT &p) : x(p.x), y(p.y) {}
于 2012-06-16T06:11:03.833 回答