C++创建对象有两种方式,在栈上创建对象(Objects on the Stack)和在堆上创建对象(Objects on the Heap)。
假设我们有以下的类:
#include <string>
using std::string; class SpreadsheetCell{
public:
void setValue(double inValue);
double getValue();
void setString(string inString);
string getString(); protected:
string doubleToString(double inValue);
double stringToDouble(string inString); double mValue;
string mString;
};
以及如下的cpp文件:
#include "stdafx.h"
#include "SpreadsheetCell.h"
#include <iostream>
#include <sstream> using namespace std; void SpreadsheetCell::setValue(double inValue){
mValue = inValue;
mString = doubleToString(mValue);
} double SpreadsheetCell::getValue(){
return mValue;
} void SpreadsheetCell::setString(string inString){
mString = inString;
mValue = stringToDouble(mString);
} string SpreadsheetCell::getString(){
return mString;
} string SpreadsheetCell::doubleToString(double inValue){
ostringstream ostr;
ostr<<inValue;
return ostr.str();
} double SpreadsheetCell::stringToDouble(string inString){
double temp; istringstream istr(inString); istr>>temp;
if(istr.fail() || !istr.eof()){
return ();
} return temp;
}
1. 在栈上创建对象(Objects on the Stack):
语法:
ClassName ObjName1, ObjName2(parameter01)// But never OjbName()
顾名思义,用这种方法创建的对象,内存分配到栈里(Stack)。使用 “.” 非 “->” 调用对象的方法。当程度离开对象的使用范围(如方法结束,一个程度块的最后{}),范围内的栈中的对象会自动删除,内存自动回收。这是创建对象最简单的方式,与“int x = 0;”是一样的。如下面例子:
SpreadsheetCell myCell, anotherCell;
myCell.setValue();
anotherCell.setValue(myCell.getValue());
cout << “cell : “ << myCell.getValue() << endl;
cout << “cell : “ << anotherCell.getValue() << endl; //destroy:
int main(int argc, char** argv)
{
SpreadsheetCell myCell();
if (myCell.getValue() == ) {
SpreadsheetCell anotherCell();
} // anotherCell is destroyed as this block ends.
cout << “myCell: “ << myCell.getValue() << endl;
return ();
} // myCell is destroyed as this block ends. //destroy in reverse order:
{
SpreadsheetCell myCell2();
SpreadsheetCell anotherCell2(); // myCell2 constructed before anotherCell2
} // anotherCell2 destroyed before myCell2
2.在堆上创建对象(Objects on the Heap):
语法:
ClassName *obj1 = new ClassName(); ClassName *obj2 = new ClassName(parameter); delete obj1; delete obj2;
用这种方法创建的对象,内存分配到堆里(Heap)。一般使用“->” 调用对象的方法。箭头操作符”->"将解引用(dereferencing*)和成员使用(member access.)结合起来,下例两个输出,效果等价:
int _tmain(int argc, _TCHAR* argv[])
{
SpreadsheetCell *myCellp = new SpreadsheetCell(); myCellp->setValue(3.7); cout<<"cell 1: "<<myCellp->getValue()<<" "<<myCellp->getString()<<endl; cout<<"cell 1: "<<(*myCellp).getValue()<<" "<<(*myCellp).getString()<<endl; delete myCellp;
return ;
}
在堆中的对象不会自动删除,内存不会自动回收,所以new一个对象使用完毕,必须调用delete,释放内存空间。也就是说,new和delete必须成对出现。
顺便提提,内存的分配方式有三种
(1)从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static 变量。
(2) 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束后在将这些局部变量的内存空间回收。在栈上分配内存空间效率很高,但是分配的内存容量有限。
(3) 从堆上分配的。程序在运行的时候用 malloc 或 new 申请任意多少的内存,程序员自己负责在何时用 free 或 delete 释放内存。
参考:
Professional C++, chapter 8