0

现在,我遇到了一个练习题:处理 CRect 类中的一些数据。但我的结果与我的预期不同。

我的代码如下:

#include<iostream>
#include<cmath>
using namespace std;
class CRect
{
public:
    void Diagonal(CRect one)
    {
        float l;
        l=sqrt( (one.right-one.left)*(one.right-one.left)+(one.bottom-one.top)*(one.bottom-one.top) );
        cout<<"The length is "<<l<<endl;
    }
    void Show(CRect one)
    {
        cout<<"("<<one.left<<","<<one.top<<")"<<"   ";
        cout<<"("<<one.right<<","<<one.bottom<<")"<<endl;
    }
    CRect(float left1,float top1,float right1,float bottom1)
    {
        left=left1;
        top=top1;
        right=right1;
        bottom=bottom1;
    }
    CRect(float left1,float top1)
    {
        left=left1;
        top=top1;
    }
    CRect(CRect &c)           
    {
        right=c.right;
        bottom=c.bottom;
    }
private:
    float left,top,right,bottom;
};

int main()
{
    CRect r1(10,10,20,20);
    CRect r2(0,0);
    r2=CRect(r1);
    r1.Show(r1);
    r1.Diagonal(r1);
    r2.Show(r2);
    r2.Diagonal(r2);
    return 0;
}

然后,结果如下图: 结果图片

我认为我没有初始化leftand top。但是,我不知道如何纠正它。我在我的代码中找不到错误。

4

5 回答 5

4

您的复制构造函数仅“初始化” 1 rightbottom,topleft留下垃圾值:

CRect(CRect &c)           
{
    right=c.right;
    bottom=c.bottom;
}

接下来,这两个参数的构造函数有类似的缺陷:

CRect(float left1,float top1)
{
    left=left1;
    top=top1;
}

您必须将所有数据成员设置为某些内容。如果这样做,您可以完全删除复制构造函数,让编译器合成一个来完成它的工作。

1为什么是引号?因为您实际上是在将值分配给至少在语义上已经初始化的数据成员。要将数据成员初始化为一个值,请使用构造函数初始化列表:CRect(float left1,float top1) : left(left1), top(top1), right(), bottom() {}

于 2013-03-21T12:39:09.343 回答
2

您的复制构造函数CRect(CRect &c)无法初始化左侧和顶部。当您将r1andr2传递给函数Diagonaland时,将调用复制构造函数Show

而且:

  1. 您根本不需要定义复制构造函数。如果您没有定义自己的,则会生成一个默认值。
  2. Show并且Diagonal是成员函数,它们不需要带参数。
于 2013-03-21T12:41:08.663 回答
1

您尚未初始化CRect(float left1,float top1)构造函数和复制构造函数中的所有成员。

CRect(const CRect &c) 
{
    right=c.right;
    bottom=c.bottom;
    top=c.top;
    left=c.left;
}

甚至可以省略您的复制构造函数并允许默认的复制构造函数执行所有操作。

更多的

CRect(float left1,float top1)
{
    left=left1;
    top=top1;
    // How about right and bottom ?!
}
于 2013-03-21T12:39:36.957 回答
0

看看你的复制构造函数

CRect(CRect &c)           
{
    right=c.right;
    bottom=c.bottom;
}

应该

CRect(CRect &c)           
{
    right=c.right;
    bottom=c.bottom;
    top=c.top;
    left=c.left
}
于 2013-03-21T12:42:55.893 回答
0

我的回答没有直接解决您的问题,但您需要养成使用构造函数初始化列表来初始化类成员成员变量的习惯。(我这样说是因为你的班级可能还没有引入初始化列表。)

例如,不要像这样从构造函数为成员变量赋值

CRect(float left1, float top1)
{
    left=left1;
    top=top1;
}

...您应该像这样初始化您的成员变量:

CRect(float left1, float top1)
    : left(left1), top(top1)
{
}

为什么,请参阅 C++ FAQ 条目[10.6] 我的构造函数应该使用“初始化列表”还是“赋值”?以及SO 上的C++ 初始化列表

在您自己的编程中,您可能还需要考虑为成员变量采用命名约定,以便更轻松地将它们与其他变量类型区分开来。例如,而不是:

private:
    float left;       // no decoration

...考虑使用两种常见约定之一:

private:
    float left_;      // trailing underscore
    float m_left;     // leading 'm_'

有关这方面的更多信息,请参阅SO 上C++ 中成员变量的尾随下划线。

于 2013-03-21T14:02:50.743 回答