C++开发初级


1048 浏览 5 years, 11 months

2.3 使用对象

版权声明: 转载请注明出处 http://www.codingsoho.com/

使用对象

前面的SpreadsheetCell类定义包含了两个成员变量、四个公有方法以及两个保护方法。然而,类定义实际上并没有创建任何SpreadsheetCell,而只是指定了单元格的形状和行为。在某种意义上,类就像是建筑蓝图。蓝图指定了房子的形状,但是绘制蓝图并没有构建任何房子,房子必须根据蓝图在后面构建。

与此类似,在C++中通过声明SpreadsheetCell类型的变量,可以根据SpreadsheetCell类的定义构建一个SpreadsheetCell“对象”。就像施工人员可以根据给定的蓝图建设多个房子一样,程序员可以根据SpreadsheetCell类创建多个SpreadsheetCell对象。可以根据两种方法来创建和使用对象:在堆栈中或者在堆中。

堆栈中的对象

下面的代码在堆栈中创建并使用了SpreadsheetCell对象。

  SpreadsheetCell myCell, anotherCell;
  myCell.setValue(6);
  anotherCell.setString("3.2");

  cout << "cell 1: " << myCell.getValue() << endl;
  cout << "cell 2: " << anotherCell.getValue() << endl;

代码取自 SpreadsheetCellNumText\SpreadsheetCellTest.cpp

创建对象类似于声明简单变量,区别在于变量类型是类名称。 "myCell.setValue(6);”中的.称为“点”运算符,这个运算符允许您调用对象的方法。如果对象中有公有数据成员,也可以用点运算符访问。

程序的输出如下:

cell 1: 6
cell 2:3.2
堆中的对象

还可以使用new动态分配对象:

  SpreadsheetCell* myCellp = new SpreadsheetCell();

  myCellp->setValue(3.7);
  cout << "cell 1: " << myCellp->getValue() <<
    " " << myCellp->getString() << endl;
  delete myCellp;
  myCellp = nullptr;

代码取自 SpreadsheetCellNumText\SpreadsheetCellHeap.cpp

当在堆中创建对象时,通过“箭头”运算符调用对象的方法或者访问数据成员。箭头运算符组合了解除引用运算符(*)以及访问方法或者成员运算符(.)。
您可以用这两个运算符替换箭头,但这么做在形式上很笨拙:

  SpreadsheetCell* myCellp = new SpreadsheetCell();

  (*myCellp).setValue(3.7);
  cout << "cell 1: " << (*myCellp).getValue() <<
    " " << (*myCellp).getString() << endl;
  delete myCellp;
  myCellp = nullptr;

代码取自 SpreadsheetCellNumText\SpreadsheetCellHeapAlternate.cpp

就如同必须释放堆中分配的其他内存一样,您必须调用delete释放堆中为对象分配的内存。为了避免发生内存错误,强烈建议使用智能指针:

  shared_ptr<SpreadsheetCell> myCellp(new SpreadsheetCell());
  myCellp->setValue(3.7);
  cout << "cell 1: " << myCellp->getValue() <<
    " " << myCellp->getString() << endl;

使用智能指针时,您不需要手动释放内存,内存会自动释放。后面将详细讨论智能指针。

提示:如果您用new为某个对象分配了内存,结束的时候要用delete销毁对象,或者使用智能指针自动管理内存。
如果您没有使用智能指针,当删除了指针所指的对象时,最好将指针重置为null。这并非强制要求,但这样做可以防止在删除对象后意外使用这个指针,这样做会使得调试更加容易。在上面的示例中,这个指针被设置为nullptr,这是C++11的特有功能。如果您的编译器不支持nullptr,则改用"myCellp=NULL"。

nullptr

nullptr能够区分指针0还是整数0

旧版本中使用NULL或0表示空指针,但存在一些隐含的问题, 看下面代码

func(int i);
func(char *);

func(NULL); //调用func(int i);

如果用调用func(char *);必须经过类型转换

func((char*)NULL);
func(static_cast<char*>NULL);

C++11定义nullptr作为空指针常量

int *p=nullptr;
func(nullptr); //强类型检查, 直接调用func(char *);