《c++入門經典》筆記11

《c++入門經典》筆記11

第十一章 開發高級指針

11.1在堆中建立對象

實際上,類就是對象的類型,對象也是一種變量,因此你能夠在堆中建立int型變量,天然也就能建立自定義型變量。ios

Cat *pCat = new Cat;c++

這將調用默認構造函數(無參構造函數),每當在堆或棧中建立對象時,都將調用構造函數。ide

11.2刪除對象

對指向堆中對象的指針調用delete時,將調用對象的析構函數,而後釋放內存。函數

程序清單11.1 HeapCreator.cppthis

#include <iostream>

class SimpleCat
{
public:
    SimpleCat()
    {
        std::cout << "Constructor called\n";
        itsAge = 1;
    }
    ~SimpleCat()
    {
        std::cout << "Destructor called\n";
    }

private:
    int itsAge;
};

int main()
{
    std::cout << "SimpleCat simpleCat ...\n";
    SimpleCat simpleCat;

    std::cout << "SimpleCat *pRags = new SimpleCat ...\n";
    SimpleCat *pRags = new SimpleCat;

    std::cout << "delete pRags ...\n";
    delete pRags;

    std::cout << "Exiting, watch simpleCat go ...\n";
    return 0;
}

這裏最後一個Destructor called是由於main()函數結束時,simpleCat對象再也不在做用域中,因此編譯器調用其析構函數。3d

11.3使用指針訪問成員

方法一(解引用運算符):指針

(*pRags).getAge();

方法二(指向運算符->):code

pRags->getAge();

程序清單11.2 HeapAccessor.cpp對象

#include <iostream>

class SimpleCat
{
public:
    SimpleCat()
    {
        itsAge = 2;
    }
    ~SimpleCat()
    {
        std::cout << "Destructor called\n";
    }
    int getAge() const { return itsAge; }
    void setAge(int age) { itsAge = age; }

private:
    int itsAge;
};

int main()
{
    SimpleCat *simpleCat = new SimpleCat;

    std::cout << "simpleCat is " << (*simpleCat).getAge() << " years old"
              << "\n";
    simpleCat->setAge(5);
    std::cout << "simpleCat is " << simpleCat->getAge() << " years old"
              << "\n";

    return 0;
}

11.4堆中的數據成員

類可能有一個或多個數據成員爲指針,並指向堆中的對象。可在構造函數或成員函數中分配內存,並在析構函數中釋放內存。blog

程序清單11.3 DataMember.cpp

#include <iostream>

class SimpleCat
{
public:
    SimpleCat()
    {
        itsAge = new int(2);
        itsWeight = new int(5);
    }
    ~SimpleCat()
    {
        delete itsAge;
        delete itsWeight;
    }
    int getAge() const { return *itsAge; }
    void setAge(int age) { *itsAge = age; }
    int getWeight() const { return *itsWeight; }
    void setWeight(int weight) { *itsWeight = weight; }

private:
    int *itsAge;
    int *itsWeight;
};

int main()
{
    SimpleCat *simpleCat = new SimpleCat;

    std::cout << "simpleCat is " << simpleCat->getAge() << " years old"
              << "\n";
    simpleCat->setAge(5);
    std::cout << "simpleCat is " << simpleCat->getAge() << " years old"
              << "\n";

    return 0;
}

11.5this指針

每一個類成員函數都有一個隱藏的參數——this指針,它指向用於調用函數的對象。

一般,在成員函數中,無需使用this指針來訪問當前對象的成員變量,若是願意,能夠顯示地使用this指針。

程序清單11.4 This.cpp

#include <iostream>

class Rectangle
{
private:
    int itsLength;
    int itsWidth;

public:
    Rectangle();
    ~Rectangle();
    void setLength(int length) { this->itsLength = length; }
    int getLength() const { return this->itsLength; }
    void setWidth(int width) { this->itsWidth = width; }
    int getWidth() const { return this->itsWidth; }
};

Rectangle::Rectangle()
{
    itsWidth = 5;
    itsLength = 10;
}

Rectangle::~Rectangle()
{
}

int main()
{
    Rectangle theRect;
    std::cout << "theRect is " << theRect.getLength() << " feet long." << std::endl;
    std::cout << "theRect is " << theRect.getWidth() << " feet wide." << std::endl;
    theRect.setLength(20);
    theRect.setWidth(10);
    std::cout << "theRect is " << theRect.getLength() << " feet long." << std::endl;
    std::cout << "theRect is " << theRect.getWidth() << " feet wide." << std::endl;
    return 0;
}

11.6懸垂指針

懸垂指針又稱爲野指針或者迷失指針,指的是對指針調用了delete(釋放其指向的內存)以後,沒有從新賦值(即沒有從新初始化)就開始被使用的指針。

實際上上章筆記中delete關鍵字時就已經提到野指針的危害。因此進行delete以後應該從新new賦值或者設置爲nullptr。

11.7const指針

聲明指針時,可在類型前、類型後或者兩個地方都使用const。

const int *pOne;//指向常量的指針
int * const pTwo;//常量指針
const int * const pThree;//指向常量的常量指針

三條語句意義各不相同,三個指針類型也各不相同。

pOne是指向整型常量的指針,也就是編譯器默認它指向的是一個常量(雖然可能不是),因此不能經過這個指針來更改所指向的常量(編譯器認爲是常量但不必定是)的值,好比*pOne = 5;編譯器就會報錯。

int one = 10;
 const int * pOne = &one;
 *pOne = 5;//報錯,表達式必須是可修改的左值,但此時*pOne被認爲不可修改

pTwo是指向整型的常量指針,能夠修改指向的整型變量,可是pTwo不能指向其餘變量。

int two = 20;
 int * const pTwo = &two;
 *pTwo = 15;
 pTwo = &one;//報錯,不能指向別的變量

pThree是一個指向整型常量的常量指針,不能修改它指向的值,也不能讓它指向其餘變量。

int three = 30;
 const int * const pThree = &three;
 pThree = &one;//報錯,不能指向別的變量
 *pThree = 25;//報錯,此時*pThree被認爲不可修改

完整代碼:(註釋起來的是報錯的)

#include <iostream>

int main()
{
    int one = 10;
    const int * pOne = &one;
//    *pOne = 5;

    int two = 20;
    int * const pTwo = &two;
    *pTwo = 15;
//    pTwo = &one;

    int three = 30;
    const int * const pThree = &three;
//    pThree = &one;
//    *pThree = 25;

    std::cout<<"one: "<<one<<" *pOne: "<<*pOne<<std::endl;
    std::cout<<"two: "<<two<<" *pTwo: "<<*pTwo<<std::endl;
    std::cout<<"three: "<<three<<" *pThree: "<<*pThree<<std::endl;
    return 0;
}

11.8const指針與const成員函數

程序清單11.5 ConstPointer.cpp

#include <iostream>

class Rectangle
{
private:
    int itsLength;
    int itsWidth;

public:
    Rectangle();
    ~Rectangle();
    void setLength(int length) { itsLength = length; }
    int getLength() const { return itsLength; }
    void setWidth(int width) { itsWidth = width; }
    int getWidth() const { return itsWidth; }
};

Rectangle::Rectangle() : itsWidth(5), itsLength(10) //初始化列表
{
}

Rectangle::~Rectangle() {}

int main()
{
    Rectangle *pRect = new Rectangle;
    const Rectangle *pConstRect = new Rectangle; //pConstRect爲指向Rectangle常量型對象的指針
    Rectangle *const pConstPtr = new Rectangle;  //pConstPtr爲指向Rectangle型對象的常量指針

    std::cout << "pRect width: " << pRect->getWidth() << " feet\n";
    std::cout << "pConstRect width: " << pConstRect->getWidth() << " feet\n";
    std::cout << "pConstPtr width: " << pConstPtr->getWidth() << " feet\n";

    pRect->setWidth(10);
    //pConstRect->setWidth(10);
    pConstPtr->setWidth(10);

    std::cout << "pRect width: " << pRect->getWidth() << " feet\n";
    std::cout << "pConstRect width: " << pConstRect->getWidth() << " feet\n";
    std::cout << "pConstPtr width: " << pConstPtr->getWidth() << " feet\n";

    return 0;
}

相關文章
相關標籤/搜索