c++ is on the way 4
问题:动态内存分配和指针之间怎么使用?
使用new,返回的内存从所谓堆(heap),即由C++运行时管理的内存区域开始分配,如何访问呢?就是使用指针,例如,
int *pNumber =new int(2001);
Star *pStar = new Star(1234.5,10.2);
当分配一个带有构造函数的对象时,初始化是强制性的。即使一个对象没有显式构造函数,编译器也可能不得不生成一些代码来构建它:
若一个类没有有效的构造函数,编译器将产生一个缺省的无参数构造函数;
若一个类有一个显式定义的无参数构造函数,则就在分配的时候调用;
若一个类只有一个带参数的构造函数,比如叫做CBody类,则CBody *bodes = new CBody[100];编译器将不予编译。
所以在定义CBody的时候可以使用如下的构造函数:CBody (double mass =0.0):_mass(mass){}
这等价于具备参数个数为0和1的两个重载构造函数。
为了释放则使用delete,例如,delete pNumber;若有析构函数则自动调用,例如,delete pStar;
若想删除数组则在其前边放上[],例如: delete [] pNumbers;
删除一个空指针是安全的,所以在调用delete前不需要检查是否为空指针。
问题:如何实现链表?
List.h
view plaincopy to clipboardprint?
#if !defined (LIST_H)
#define LIST_H
// (c) Bartosz Milewski 2000
class Link
{
public:
Link (Link* pNext, int id)
: _pNext (pNext), _id (id) {}
Link * Next () const { return _pNext; }
int Id () const { return _id; }
private:
int _id;
Link * _pNext;
};
class List
{
public:
List (): _pHead (0) {}
~List ();
void Add ( int id );
Link const * GetHead () const { return _pHead; }
private:
Link* _pHead;
};
#endif
#if !defined (LIST_H)
#define LIST_H
// (c) Bartosz Milewski 2000
class Link
{
public:
Link (Link* pNext, int id)
: _pNext (pNext), _id (id) {}
Link * Next () const { return _pNext; }
int Id () const { return _id; }
private:
int _id;
Link * _pNext;
};
class List
{
public:
List (): _pHead (0) {}
~List ();
void Add ( int id );
Link const * GetHead () const { return _pHead; }
private:
Link* _pHead;
};
#endif
List.cpp
view plaincopy to clipboardprint?
// (c) Bartosz Milewski 2000
#include "List.h"
#include <iostream>
List::~List ()
{
// free the list
while ( _pHead != 0 )
{
Link* pLink = _pHead;
_pHead = _pHead->Next(); // unlink pLink
delete pLink;
}
}
void List::Add ( int id )
{
// add in front of the list
Link * pLink = new Link (_pHead, id);
_pHead = pLink;
}
int main ()
{
List list;
list.Add (1);
list.Add (2);
std::cout << "List contents: ";
for (Link const * pLink = list.GetHead();
pLink != 0;
pLink = pLink->Next ())
{
std::cout << pLink->Id() << ", ";
}
std::cout << std::endl;
}
// (c) Bartosz Milewski 2000
#include "List.h"
#include <iostream>
List::~List ()
{
// free the list
while ( _pHead != 0 )
{
Link* pLink = _pHead;
_pHead = _pHead->Next(); // unlink pLink
delete pLink;
}
}
void List::Add ( int id )
{
// add in front of the list
Link * pLink = new Link (_pHead, id);
_pHead = pLink;
}
int main ()
{
List list;
list.Add (1);
list.Add (2);
std::cout << "List contents: ";
for (Link const * pLink = list.GetHead();
pLink != 0;
pLink = pLink->Next ())
{
std::cout << pLink->Id() << ", ";
}
std::cout << std::endl;
}
我们要注意区分的是指向常量的指针和常量指针,前者所指向的想对象不能通过此指针来修改,后者则表示一旦初始化,就不能指向其他任何对象。
Link const *pLink;//指向常量的指针
Link * const pLink = pInitPtr;//常量指针
可以组合为指向常量的常量指:
Link Const * const pLink=pInitPtr;
我们从右往左念,星号表示“指向一个”,这样就好理解记忆了。
另外,const作为返回值的一些东西也需要我们注意:我们经常看到一些函数返回const char*后者返回char *,这有什么区别呢?
const char*说明函数返回一个你不能改变指针所指向单元值的指针. 也就是说指针所指向的值是一个常数,你不能通过*操作来改变它的值.
而char*则可以改变指针所指向的值.要是不需要处理返回值,或者不允许处理返回值的话,那么其实使用前者比较好。再一个问题:用const修饰引用,通过引用本身不可修改其值,但这并不耽误被引用变量的被外界修改。Const加在数据类型前后均可。
例如:void main(void)
{
int i = 10;
int j = 100;
const int &r = i;
int const &s = j;
r = 20; //错,不能改变内容
s = 50; //错,不能改变内容
i = 15; // i和r 都等于15
&nb
补充:软件开发 , C++ ,