2015-04-02 101 views
1

在我的面向对象的C++课程中,我们必须编写这个类,我已经在下面提到了。C++类的成员函数:如何编写这些函数?

Point 
    class Point{ 
    public: 
     Point(double x = 0, double y = 0); 
     double getX() const; 
     double getY() const; 
     Point & setX(double x); // mutator, returning reference to self 
     Point & setY(double y); 
     const Point & output() const; 
     double distance(const Point & other) const; 
    private: 
     double xPoint, yPoint; 
    }; // class Point 

我的问题是...我找不到任何有关函数setX,setY和输出如何工作的信息。它们与班级本身是同一类型的,我写了我期望它们看起来像下面的内容。任何人都可以告诉我我做错了什么,也许有关这些功能如何工作的更多细节? setX函数应该改变对象中的xPoint,setY应该对yPoint执行相同的操作,输出应该简单地输出它们。

Point & Point::setX(double x) 
{ 
xPoint = x; 
} 

Point & Point::setY(double y) 
{ 
Ypoint = y; 
} 

const Point & Point::output() const 
{ 
cout << xPoint << yPoint; 
} 
+2

只需在setX和setY的末尾添加一个返回'* this'即可:例如,您可以这样做:'p0.setX(1.23).setY(3.45)' ,当然'p0'是Point的一个实例。在输出函数中,在xPoint和yPoint之间放置一个分隔符,就像一个空格。你说'它们和类本身是一样的类型':不要将变量类型与函数/方法返回的类型混淆:那些方法返回它们所属的类的一个实例。 – Antonio 2015-04-02 23:30:25

+2

'setY'中还有一个小错字:它应该是'yPoint',而不是'Ypoint'。 C++区分大小写。 – 5gon12eder 2015-04-02 23:34:35

+0

非常感谢!你能详细说明为什么把这个指针用于这些函数吗? – 2015-04-02 23:39:51

回答

3

只需在setX的和SETY的末尾添加return *this;:您返回到您的对象的引用,这样,例如,你可以这样做:p0.setX(1.23).setY(3.45),与当然p0点的一个实例。在输出函数中,在xPoint和yPoint之间放置一个分隔符,就像一个空格。您说They are the same type as the class itself:不要将变量类型与函数/方法返回的类型混淆:方法setXsetYoutput会返回对它们所属类的实例的引用。请注意,由输出返回的引用是const,所以你可以做:

p0.setX(1.23).setY(3.45).output(); 

但不是:

p0.output().setX(1.23); 

由于setX不是一个常量方法(不声明它不会修改其所属类实例内的数据)。

你可以打电话来代替:

double x = p0.output().getX(); 

因为getX是一个const方法。

注意:我不是说你应该以这种方式使用这些方法,但重点是展示你可以做什么。

0

二传手是公共metods这就是让你改变类的私有成员,他们没有返回类型,因此setXsetY应该是voidPoint

void set(double x); // Declaration 
void Point::setX(double x) // Definition outside Point.h 
{ 
    xPoint = x; 
} 

同样的,outputvoid,休息是好的,你可以定义为任何你想要显示它,你可以这样改:

void Point::output() const 
{ 
    cout << "(" << xPoint << ", " << yPoint << ")"; 
} 
+1

我完全同意,但这是我的教授希望我们做的事情,我们让他们为空,我们必须改变他们。 – 2015-04-02 23:43:33

0

setX()将普罗巴bly更改pointX成员的值,并返回对正在执行的对象的引用。

所以实现可能是这样的

Point &Point::setX(double xval) 
{ 
    if (IsValid(xval)) pointX = xval; // ignore invalid changes 
    return *this; 
} 

这可以(假设其他成员函数和运算符的使用是否正确)的东西像这样使用

#include <iostream> 
// declaration of Point here 
int main() 
{ 
    Point p; 
    std::cout << p.setX(25).setY(30).getX() << '\n'; 
} 

虽然这个例子ISN”特别有用(它表明什么是可能的)成员函数调用的链接在各种情况下都是有用的。例如,这种技术实际上是插入和提取操作符工作的基础,并允许在单个语句中将多个事物插入/提取到流中/从流中提取。

0

setXsetY功能文档说

// mutator, returning reference to self 

你实现执行突变,但你没能完成这个功能要满足合同:它应该回报对自己的参考

this是一个指向对象的指针,你是在调用的方法,所以加入一行

return *this; 

将完成合同。


这是旁白,但它可以帮助你理解为什么有人会想要使用这种'奇怪'的设计。

您可能熟悉与普通分配的方式使用,如

a = b = 0; 

if((result = some_function()) == 0) { 
    // Do something in the `result == 0` case 
} else { 
    // Do something in the `result != 0` case 
} 

和其他类似的东西。第一个示例将ab都设置为0。第二个示例将函数调用的返回值存储到变量result中,然后根据该值是否为0进行分支。

此工作的方式是,x = y二元运算即具有复制的y值存入x的副作用,然后返回该值(技术上x参考),以便它可以使用在周围的表达。

所以,当你写a = b = 0,这被分析为a = (b = 0),并且具有对b零的效果,然后评估为a = 0然后进行评估,使a为零。类似的分支示例。

这是人们在编写代码时所喜欢做的事情(这是一个完全独立的主题,无论这是否是好的风格),所以当人们使用operator=方法设计新类型时,他们设计它们以支持这种用法,返回分配给对象的引用。例如

MyClass& MyClass::operator=(arg a) 
{ 
    // Copy the value of `a` into this object 
    return *this; 
} 

其他赋值运算符,如operator+=也可以这种方式工作。

现在,当您习惯了这种用法时,将它扩展到像分配一样行事的其他功能,如setXsetY是一小步。这样可以更方便地进行链修改,如point.setX(3).setY(7)

+0

非常感谢!现在我明白'* this'是一个解除引用的指针,并且*这通常指向当前对象的克隆,但是由于它正在返回一个引用,它将返回到当前对象。如果没有星号,我们不能返回这个原因是什么原因? – 2015-04-03 00:06:40