为什么我必须将指针初始化为变量?

时间:2013-05-16 03:54:49

标签: c++

下面这段代码工作正常。 //构造函数和析构函数的示例

#include <iostream>
using namespace std;

class CRectangle {
    int *width, *height;
  public:
    CRectangle (int,int);
    ~CRectangle ();
    int area () {return (*width * *height);}
};

CRectangle::CRectangle (int a, int b) {
  width = new int;
  height = new int;
  *width = a;
  *height = b;
}

CRectangle::~CRectangle () {
  delete width;
  delete height;
}

int main () {
  CRectangle rect (3,4), rectb (5,6);
  cout << "rect area: " << rect.area() << endl;
  cout << "rectb area: " << rectb.area() << endl;
  return 0;
}

但为什么我不能在下面使用另一段代码呢?它没有使用下面的代码编译,但如果我强制运行它仍然会产生正确的结果。

#include <iostream>
using namespace std;

class CRectangle {
  //here I didn't initialize these two variables' pointers.
  int width, height;
public:
  CRectangle (int a,int b);
  ~CRectangle ();
  int area () {
    return (width * height);
  }
};

CRectangle::CRectangle (int a, int b) {
  width = a;
  height = b;
}

CRectangle::~CRectangle () {

}

int main () {
  CRectangle rect (3,4), rectb (5,6);
  cout << "rect area: " << rect.area() << endl;
  cout << "rectb area: " << rectb.area() << endl;
  return 0;
}

2 个答案:

答案 0 :(得分:3)

在你的第二段代码中

int area () {
   return (*width * *height);
}

.
.
.

CRectangle::~CRectangle () {
  delete width;
  delete height;
}
<{1>}中的

,您取消引用return (*width * *height);width这些不是指针。此外,在您的析构函数中,您height deletewidth不是使用height初始化的指针,因此无效操作。什么是正确的

new

另外,正如@chris在评论中指出的那样,你也可以删除析构函数(确保删除声明和定义)。

答案 1 :(得分:1)

这里有一个结构,其中包含两个指向整数的指针,这些整数必须位于内存中的其他位置。因此,当创建CRectangle时,有三个新对象:CRectangle本身,然后是其他两个整数。

在面向对象的编程术语中,CRectange通过聚合与两个int对象相关联。

#include <iostream>
using namespace std;

class CRectangle {
    int *width, *height;
  public:
    CRectangle (int,int);
    ~CRectangle ();
    int area () {return (*width * *height);}
};

现在,情况有所不同:int内嵌有两个CRectangle个对象。当您创建CRectangle对象时,其中已存在那些整数。它们在内存中有一个地址,所以你可以指向它们,但是 它们是相对于CRectangle的地址访问的。在CRectangle的成员函数内,当您访问width时,它实际上意味着this->width。涉及对象的指针,但不可见。如果我们有指向对象的指针,那么它的字段只能通过相对于指针的位移来找到。由于C ++不是汇编语言,编译器会为您计算出这个位移计算并生成机器代码。

CRectangle与两个整数之间的关联现在是组合

class CRectangle {
  //here I didn't initialize these two variables' pointers.
  int width, height;
public:
  CRectangle (int a,int b);
  ~CRectangle ();
  int area () {
    return (*width * *height);
  }
};

area函数中,您不应该使用一元运算符*进行指针解除引用,因为widthheight不是指针。它不适用。 (请确保您的示例在发布之前干净地编译,除了专门说明一些麻烦的非编译的示例。)