当前位置:编程学习 > C/C++ >>

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++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,