《c++入門經典》筆記11
第十一章 開發高級指標
11.1在堆中創建物件
實際上,類就是物件的型別,物件也是一種變數,所以你可以在堆中創建int型變數,自然也就能創建自定義型變數,
Cat *pCat = new Cat;
這將呼叫默認建構式(無參建構式),每當在堆或堆疊中創建物件時,都將呼叫建構式,
11.2洗掉物件
對指向堆中物件的指標呼叫delete時,將呼叫物件的解構式,然后釋放記憶體,
程式清單11.1 HeapCreator.cpp
#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物件不再在作用域中,所以編譯器呼叫其解構式,
11.3使用指標訪問成員
方法一(解參考運算子):
(*pRags).getAge();
方法二(指向運算子->):
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堆中的資料成員
類可能有一個或多個資料成員為指標,并指向堆中的物件,可在建構式或成員函式中分配記憶體,并在解構式中釋放記憶體,
程式清單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;
}

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/1847.html
標籤:C++
上一篇:《c++入門經典》筆記10
下一篇:Floyd演算法詳(cha)解
