(GeekBand)C++面向对象之有指针类

1.带指针类设

带指针类必须含有拷贝构造、拷贝赋值以及析构函数。

1.String类解析

在string类中有一个私有的指针指向内存中的字符串,当我们需要使用这个字符串时才通过指针去申请内存。

class string
{
public:
        //构造函数,如果传入空指针,则初始化为0
        string( const char* cstr = 0 );
        //拷贝构造函数
        string( const String& str );
        //重载运算符" = ",实现拷贝赋值
        string& operator = ( const string& str );
        ~string();

        //
        char* get_c_str() const { return m_data; }

private:
        char* m_data;
};

inline
string::string( const char* cstr )
{
    if( cstr )
    {
        m_data = new char[ strlen(cstr)+1 ];
        strcpy( m_data, cstr );
    }
    //未指定初值,传入了空指针
    else
    {
        m_data = new char[1];
        *m_data = '\0';
    }
}

inline
string& string::operator = ( const string& str )
{
    //如果this指针的地址与str的地址相同,则为自我赋值。
    if( this == &str ) return *this;
    else
    {
        delete[] m_data;
        m_data = new char[ strlen(str.m_data)+1 ];
        strcpy( m_data, str.m_data );
        return *this;
    }
}

//拷贝构造函数
inline
string::string( const string& str )
{
    //使用str.m_data直接获取私有变量,因为各个对象互为friend
    m_data = new char[ strlen( str.m_data )+1 ];
    strcpy( m_data, str.m_data );
}

//假如我们在一个作用域内定义了一个对象,当离开该作用域时,会自动调用析构函数释放该对象的内存
inline
string::~string()
{
    delete[] m_data;
}

2.关于栈(stack),堆(heap)

1.栈(stack)

stack存在于某个scope的一块内存空间。当调用某函数时,函数本身会形成一个stack来放置它所接收的参数、返回地址以及local objects。
在函数本体(function body)内声明的任何变量,其所用的内存块都取自上述stack。

2.堆(heap)

所谓system heap,是指由操作系统提供的一块global内存空间,程序可动态分配从其中获得若干区块。

举例:
class complex
{ ... };
......
//对象C定义在任何作用域之外,因此是全局对象,作用域与static一样是整个程序。
complex C( 1, 2 );

{
    //c1所占空间来自栈,它在作用域结束后会被自动清理,因此称其为local object或auto object。
    complex c1( 1, 2 ); 

    //c2的生命在其scope结束之后依旧存在,直到整个程序结束。
    static complex c2( 1, 2 );

    //使用new新建对象时,是先分配memory再调用ctor,在作用域结束后p依旧存在。
    complex* p = new complex( 1, 2 ); 
    //这里的单元由内存动态分配得来,因此用户有义务将其删除。
    delete p;
}
分析:
1.用new创建单个对象:
complex* pc = new complex( 1, 2 );

上面一句代码在编译器中做了如下工作:

complex *pc;

void* mem = operator new( sizeof( complex ) );//内部调用malloc分配内存。
pc = static_cast( mem );//转型
pc->complex::complex( 1, 2 );
2.使用delete释放内存:
String* pc = new String( "Hello!" );
...
delete pc;

这句代码在编译器中是先调用dtor,再释放内存。

complex::~complex( pc );//析构函数,将内存中的String释放。
operator delete( pc );//释放指针的内存,内部调用free( pc )。
如果使用array new建立一个数组时,必须用delete[] 来进行内存释放。

你可能感兴趣的:((GeekBand)C++面向对象之有指针类)