日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 人文社科 > 生活经验 >内容正文

生活经验

C++:随笔5---this指针和类的继承

發(fā)布時(shí)間:2023/11/27 生活经验 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++:随笔5---this指针和类的继承 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

this指針:(通過(guò)一個(gè)典型的例子來(lái)認(rèn)識(shí)他)

class Human
{char fishc;Human(char fishc);//構(gòu)造函數(shù)};
Human::Human(char fishc)//對(duì)構(gòu)造函數(shù)進(jìn)行初始化
{fishc=fishc;//意圖就是把這個(gè)傳入?yún)?shù)賦值給這個(gè)上邊類屬性的fishc
}
//但是這樣賦值的話,他們的名字一樣,這樣的話構(gòu)造器就有可能認(rèn)不出來(lái),(因?yàn)樗恢滥闶且褜傩匀ジ采w參數(shù),還是把傳入的參數(shù)去覆蓋給屬性,因?yàn)閮烧叩拿忠粯?#xff0c;但是語(yǔ)法沒(méi)有錯(cuò)。他們是兩個(gè)不同區(qū)域的一個(gè)是傳入的參數(shù),一個(gè)是類的屬性,(因?yàn)樗麄兾挥趦蓚€(gè)不同的區(qū)域,所以語(yǔ)法上沒(méi)有錯(cuò)))//所以怎么讓構(gòu)造器知道哪個(gè)是參數(shù)哪個(gè)是屬性呢?這個(gè)時(shí)候就需要用到this指針。
this->fishc=fishc;//this指針是指向當(dāng)前的類生成的對(duì)象//所以就很明顯前者是類的屬性,后邊是參數(shù)。
//這樣的話編譯器就懂了,賦值操作符的左邊將被解釋為當(dāng)前對(duì)象的fishc屬性,右邊將被解釋為構(gòu)造器的傳入來(lái)的fishc的參數(shù)。

//PS:注意使用this指針的基本原則是如果代碼不存在二義性隱患,就不必使用this指針。

------------類的繼承-------

繼承機(jī)制使得程序員可以創(chuàng)建一個(gè)類的堆疊層次結(jié)構(gòu),每個(gè)子類均將繼承在他的基類里定義的方法和屬性。(在繼承原有方法的同時(shí),再增加另外的一些屬性的方法)(通過(guò)繼承機(jī)制可以對(duì)現(xiàn)有的代碼進(jìn)行進(jìn)一步的擴(kuò)展,并應(yīng)用在新的程序中)

(1)他們都是動(dòng)物的子類。我們可以編寫一個(gè)Animal作為Turtle和Pig的基類。

繼承類的語(yǔ)法:

//語(yǔ)法:
class SubClass:public Superclass{...}
//例子:
class Pig:public Animal{...}

基類是可以派生出其他的類,也稱為父類和超類;子類是從基類派生出來(lái)的類(比如Turtle類和Pig類)。

??

實(shí)現(xiàn)如下:

#include<iostream>
#include<string>
class Anmial//聲明一個(gè)基類
{public:std::string mouth;void eat();void sleep();void drool();
};
//繼承基類
class Pig:public Animal
{public:void climb();
};
class Turtle:public Animal
{public:void swim();
};
//對(duì)上述方法進(jìn)行補(bǔ)充
void Animal::eat()
{std::cout<<"我正在吃"<<std::endl;
}
void Animal::sleep()
{std::cout<<"我正在睡覺(jué)"<<std::endl;
}
void Animal::eat()
{std::cout<<"我正在流口水"<<std::endl;
}//上述把基類的三個(gè)方法給搞定了
//下面實(shí)現(xiàn)子類的方法(不管他們是基類還是父類,他們都是方法就按照類的方法實(shí)現(xiàn)來(lái)寫)
void Pig::climb()
{std::cout<<"我會(huì)爬樹(shù)"<<std::endl;
}
void Turtle::swim()
{std::cout<<"我會(huì)游泳"<<std::endl;
}
int main()
{//對(duì)類進(jìn)行實(shí)例化Pig pig;Turtle turtle;pig.sleep();turtle.sleep();pig.climb();turtle.swim();}

------帶參數(shù)的構(gòu)造器----

//構(gòu)造器帶著輸入?yún)?shù)
//1、聲明
class Animal
{public:Animal(std::string thename);std::string name;
};
class Pig:public Animal
{public:Pig(std::string thename);};
//2、方法定義
Animal::Animal(std::string thename)
{name=thename;
}
Pig::Pig(std::string thename):Animal(thename)//Pig的構(gòu)造器繼承Animal的構(gòu)造器
{}

因?yàn)镻ig的方法里面是空的,他是直接繼承于Animal的方法的。

------訪問(wèn)控制--------

上述類的所有成員都是用public:語(yǔ)句聲明。

所謂的訪問(wèn)控制就是c++提供了一種用來(lái)保護(hù)類里的方法和屬性的手段。

??

-------覆蓋------

既有共同特征又需要在不同類里有不同的實(shí)現(xiàn)方法)意思就是在類里邊重新聲明一下這個(gè)方法,他的函數(shù)名字參數(shù)返回值一摸一樣(不然的話就會(huì)變成重載了)。

例子:為Animal添加eat方法,并在子類中進(jìn)行覆蓋。

-------重載方法--------

繼承之后不能重載。(子類里邊不能重載)

----友元-------

? ?

聲明另外一個(gè)類是這個(gè)類的友元類,友元關(guān)系是類之間的一種特殊關(guān)系,這種特殊關(guān)系不僅允許友元類訪問(wèn)對(duì)方的public方法和屬性,還允許友元訪問(wèn)對(duì)方的protected和private方法和屬性。

聲明一個(gè)友元關(guān)系的語(yǔ)法,在類聲明里的某個(gè)地方加上一條friend class **就行了(其中**表示你需要友元的另一個(gè)類的那個(gè)名字)。

注意這條語(yǔ)句可以放在任何地方,放在public,protected和private段落里邊都可以。(這樣之后他們兩個(gè)人就相當(dāng)于是同一個(gè)人)

例子:定義Lovers這個(gè)類,有兩個(gè)子類Boyfriend和Girlfriend。Lovers類的方法kiss()和ask();第三者Others類,想要kiss()Girlfriend類的對(duì)象。

#include<stdio.h>
#include<iostream>class Lovers
{public:Lovers(std::string theName);//構(gòu)造函數(shù),就是給他命名void kiss(Lovers* lover);//參數(shù)聲明一個(gè)指針,void ask(Lovers* lover,std::string something);protected:std::string name;friend class others;//這時(shí)候others跟Lovers就是一對(duì)。
};
class Boyfriend:public Lovers
{public:Boyfriend(std::string theName);
};
class Girlfriend:public Lovers
{public:Girlfriend(std::string theName);
};
class Others
{public:Others(std::string theName);void kiss(Lovers* lover);protected:std::string name;//Lover->name屬于這個(gè)類的protected
};
Lovers::Lovers(std::string theName);
{name=theName;//構(gòu)造函數(shù)給它命名,也就是說(shuō)我們?cè)煲粋€(gè)人出來(lái)的時(shí)候,
}
void Lovers::kiss(Lovers* lover)
{std::cout<<name<<"親親"<<lover->name<<std::endl;
}
void Lovers::ask(Lovers* lover,std::string something)
{std::cout<<Lover->name<<"幫我"<<something<<std::endl;
}
//子類
Boyfriend::Boyfriend(std::string name):Lovers(theName)
{}
Girlfriend::Girlfriend(std::string name):Lovers(theName)
{}
//友元類
Others::Others(std::string theName);
{name=theName;//構(gòu)造函數(shù)給它命名,也就是說(shuō)我們?cè)煲粋€(gè)人出來(lái)的時(shí)候,
}void Others::kiss(Lovers* lover)//這個(gè)里邊的參數(shù)引用到了lover
{std::cout<<name<<"吻一下"<<lover->name<<std::endl;//lover->name屬于這個(gè)Lovers類的protected,不是這個(gè)類的子類根本訪問(wèn)不到,而others不是它的子類,所以理論上是訪問(wèn)不到的,這里因?yàn)樯线吺莊riend class others;所以可以訪問(wèn)到。
}
//主函數(shù)
int main()
{Boyfriend boyfriend("A君");//造一個(gè)人出來(lái)給它命名叫做A君(構(gòu)造函數(shù))Girlfriend girlfriend("B妞");//叫做B妞Others others("路人甲");//others這個(gè)陌生人叫做路人甲girlfriend.kiss(&boyfriend);//因?yàn)閰?shù)是指針?biāo)詡鬟M(jìn)去的應(yīng)該是對(duì)象的地址girlfriend.ask(&boyfriend,"拖地")std::cout<<"傳說(shuō)中的友元類,路人甲出現(xiàn)了\n"<<std::endl;others.kiss(&girlfriend);return 0;
}

-------靜態(tài)屬性和靜態(tài)方法-------

創(chuàng)建一個(gè)靜態(tài)屬性和靜態(tài)方法:只需要在他的聲明前加上static保留字即可。

#include<string>
#include<iostream>class Pet
{public:Pet(std::string theName);//帶參數(shù)的構(gòu)造器~Pet();static int getCount();//這里作為一個(gè)接口,用來(lái)給他由他生成的對(duì)象來(lái)獲取他這個(gè)計(jì)數(shù)器protected:std::string name;private://private是這個(gè)類里的方法才能夠調(diào)用的,getCount()函數(shù)可以調(diào)用//private成員只有這個(gè)類里邊的方法才能夠訪問(wèn)它static int count;//私有成員,一個(gè)count計(jì)數(shù)器
};
class Dog :public Pet//繼承Pet類
{public:Dog(std::string theName);~Dog();
};
class Cat :public Pet//繼承Pet類
{public:Cat(std::string theName);~Cat();
};
int Pet::count = 0;//這一句做了兩件事;第一:讓編譯器為count這個(gè)變量的值分配內(nèi)存;第二:這個(gè)變量因?yàn)槭窃陟o態(tài)存儲(chǔ)區(qū),他是把這個(gè)變量初始化為0;
Pet::Pet(std::string theName)//構(gòu)造函數(shù),當(dāng)該構(gòu)造函數(shù)被調(diào)用的時(shí)候說(shuō)明這個(gè)寵物已經(jīng)被建造出來(lái)了
{name = theName; count++;//那么這個(gè)計(jì)數(shù)器就加一std::cout << "一只寵物變出來(lái)了,名字叫做:" << name << std::endl;
}
Pet::~Pet()//析構(gòu)器
{count--; //析構(gòu)器說(shuō)明這個(gè)寵物已經(jīng)掛掉了,所以計(jì)數(shù)器要減掉std::cout << name << "掛掉了" << std::endl;
}
int Pet::getCount()//這個(gè)接口函數(shù)getCount()的唯一作用,把這個(gè)count返回出來(lái),把他拿到的這個(gè)私有成員返回出來(lái),然后show出來(lái)
{return count;//是為了任何代碼都可以通過(guò)調(diào)用getCount()函數(shù)(因?yàn)槭莗ublic)從而來(lái)讀取該屬性count的值(因?yàn)樵撝凳莗rivate,所以對(duì)該屬性只能是讀不能是寫,只有在Pet的析構(gòu)函數(shù)和構(gòu)造函數(shù)才能夠?qū)λM(jìn)行寫)
}
Dog::Dog(std::string theName) :Pet(theName)//Dog的構(gòu)造器繼承Pet的構(gòu)造器
{//std::cout<<"this:"<<this<<endl;//1生成一個(gè)dog對(duì)象之后就把this指針給打印出來(lái)//按此它生成一個(gè)dog對(duì)象的時(shí)候this指針應(yīng)該是指向dog對(duì)象的。下邊生成dog對(duì)象
}
Dog::~Dog()
{}
Cat::Cat(std::string theName) :Pet(theName)
{}
Cat::~Cat()
{}
int main()
{Dog dog("Tom");//整了一只狗dog叫做Tom(繼承構(gòu)造器的實(shí)現(xiàn))//用Dog類生產(chǎn)出dog對(duì)象Cat cat("Jerry");//整了一只貓叫做Jerrystd::cout<<"dog:"<<&dog<<std::endl;//2這里生成dog對(duì)象之后,我們把dog也給打印出來(lái)std::cout << "已經(jīng)誕生了" << Pet::getCount() << "只寵物!\n\n";//顯示出來(lái)//getCount()函數(shù)調(diào)用私有成員count{//注意這里的大括號(hào),是有作用的。這里相當(dāng)于是一個(gè)區(qū)域Dog dog_2("Tom_2");//又整了一只狗Cat cat_2("Jerry_2");//又整了一只貓std::cout << "現(xiàn)在呢,已經(jīng)誕生了" << Pet::getCount() << "只寵物!\n\n";}//到此之前還剩下兩只,因?yàn)榇罄ㄌ?hào)之后析構(gòu)函數(shù)了,把寵物給毀掉std::cout << "\n現(xiàn)在還剩下" << Pet::getCount() << "只寵物!\n\n";return 0;//return 0的時(shí)候一只寵物都沒(méi)有了,因?yàn)槲鰳?gòu)函數(shù)了,把寵物給毀掉
}
//上述1和2處打印的地址完全一樣

結(jié)果:右邊結(jié)果是去掉main函數(shù)中間的大括號(hào)的

? ?

static靜態(tài)變量的詳解:https://www.cnblogs.com/dc10101/archive/2007/08/22/865556.html

靜態(tài)成員是所有對(duì)象共享的,所以不能在靜態(tài)方法里訪問(wèn)非靜態(tài)的元素。

非靜態(tài)方法可以訪問(wèn)類的靜態(tài)成員,也可以訪問(wèn)類的非靜態(tài)成員。

C++內(nèi)存分配方式詳解——堆、棧、自由存儲(chǔ)區(qū)、全局/靜態(tài)存儲(chǔ)區(qū)和常量存儲(chǔ)區(qū):https://fishc.com.cn/blog-9-1097.html

this指針:this指針是類的一個(gè)自動(dòng)生成,自動(dòng)隱藏的私有成員,它存在于類的非靜態(tài)成員函數(shù)中,指向被調(diào)用函數(shù)所在的對(duì)象的地址。(也就是說(shuō)我生成每一個(gè)對(duì)象的時(shí)候,它都會(huì)自動(dòng)生成一個(gè)this指針,這個(gè)指針指向的是對(duì)象它的一個(gè)地址)當(dāng)一個(gè)對(duì)象被創(chuàng)建時(shí),該對(duì)象的this指針就會(huì)自動(dòng)指向?qū)ο髷?shù)據(jù)的首地址。

#include<iostream>
class Point
{private:int x,y;public:point(int a,intb){x=a;y=b}void MovePoint(int a,int b){x=a;y=b;}void print(){ std::cout<<"x="<<x<<"y="<<y<<endl;}
};
int main()
{Point point1(10,10);//用Point這個(gè)類生產(chǎn)出Point1這個(gè)對(duì)象。這個(gè)點(diǎn)的坐標(biāo)在(10,10)這個(gè)位置Point1.MovePoint(2,2);point1.print();return 0;
}
//當(dāng)對(duì)象point1調(diào)用MovePoint這個(gè)成員的時(shí)候,(實(shí)時(shí)上我們生成point1這個(gè)對(duì)象的時(shí)候,就有一個(gè)this指針指向point1的地址),當(dāng)他調(diào)用MovePoint這個(gè)函數(shù)的時(shí)候,即將point1對(duì)象的地址傳遞給this指針,(因?yàn)槲覀冃枰玫降氖莗oint1這個(gè)對(duì)象的成員,那我們就必須知道這個(gè)對(duì)象的地址,就必須傳遞給this指針)
//MovePoint函數(shù)的原型事實(shí)上應(yīng)該是 void MovePoint(Point* this,int a,int b);他有三個(gè)參數(shù),一個(gè)是隱含的this指針?biāo)赶騊oint對(duì)象(第一個(gè)參數(shù)是指向該類對(duì)象的一個(gè)指針,我們?cè)诙x成員函數(shù)時(shí)沒(méi)看見(jiàn)是因?yàn)檫@個(gè)參數(shù)在類中是隱含的,是C++的一個(gè)規(guī)則,因?yàn)槊恳粋€(gè)都是默認(rèn)添加進(jìn)第一個(gè)規(guī)則)。
//這樣子pOint1的地址就傳遞給this,所以在MovePoint()函數(shù)中便可以顯示的寫成void MovePoint(int a,int b)(this->x=a;this->y=b)(其實(shí)也可以x=a,這樣編譯器知道哪一個(gè)是參數(shù)哪一個(gè)是變量,用this做區(qū)分)
//我們這樣就可以知道point1調(diào)用該函數(shù)后,也就是point1的數(shù)據(jù)成員被調(diào)用并更新了值。

?

總結(jié)

以上是生活随笔為你收集整理的C++:随笔5---this指针和类的继承的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。