国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【C++】繼承(通俗易懂,超級詳細)

這篇具有很好參考價值的文章主要介紹了【C++】繼承(通俗易懂,超級詳細)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

? 本篇文章會對c++中的繼承進行講解。其中講解了繼承的概念及定義、基類和派生類對象賦值轉換、繼承中的作用域、派生類的默認成員函數 和 復雜的菱形繼承及菱形虛擬繼承等內容。希望本篇文章會對你有所幫助。

【C++】繼承(通俗易懂,超級詳細),C++,c++,開發(fā)語言

文章目錄

一、繼承的概念及定義

1、1 繼承的概念

1、2 繼承的定義

二、基類和派生類對象賦值轉換

三、繼承中的作用域

四、派生類的默認成員函數

五、繼承與友元

六、繼承與靜態(tài)成員

七、菱形繼承和菱形虛擬繼承

7、1 單繼承、多繼承和菱形繼承

7、2 菱形繼承存在的問題

7、3 菱形虛擬繼承

7、3、1?菱形虛擬繼承的認識

7、3、2?菱形虛擬繼承的實現原理

八、繼承的總結和反思

九、總結


???♂??作者:@Ggggggtm????♂?

???專欄:C++? ??

???標題:list講解??

????寄語:與其忙著訴苦,不如低頭趕路,奮路前行,終將遇到一番好風景?????

【C++】繼承(通俗易懂,超級詳細),C++,c++,開發(fā)語言

一、繼承的概念及定義

1、1 繼承的概念

??C++是一種支持面向對象編程(Object-Oriented Programming)的編程語言,面向對象的三大特性:封裝、繼承、多態(tài)。繼承(inheritance)是C++中重要的特性之一。

? 繼承(inheritance)機制是面向對象程序設計使代碼可以復用的最重要的手段,它允許程序員在保持原有類特性的基礎上進行擴展,增加功能,這樣產生新的類,稱派生類。繼承呈現了面向對象程序設計的層次結構,體現了由簡單到復雜的認知過程。以前我們接觸的復用都是函數復用,繼承是類設計層次的復用。

? C++中的繼承可以通過派生類(derived class)基類(base class)中派生出來?;愂且呀浂x好的類,而派生類則是基于基類的定義創(chuàng)建出來的新類。(派生類又名子類,基類又名父類)。

? 舉個例子:假如我們要對學生和老師信息進行管理,我們分別需要創(chuàng)建class Student和 class Teacher 類。但是我們發(fā)現這兩個類有很多共同的屬性(_name,_age)。能不能把共同的屬性和方法提出到一個類中呢?答案是可以的!

【C++】繼承(通俗易懂,超級詳細),C++,c++,開發(fā)語言? ?我們把具有共同的屬性和方法的類稱為基類,class Student 和 class Teacher 類這兩個類再次繼承基類。這兩個類中也有基類的屬性和方法。具體也可結合如下代碼理解:

class Person
{
public:
 void Print()
 {
  cout << "name:" << _name << endl;
  cout << "age:" << _age << endl;
 }
protected:
 string _name = "peter"; // 姓名
 int _age = 18; ?// 年齡
};
// 繼承后父類的Person的成員(成員函數+成員變量)都會變成子類的一部分。這里體現出了
// Student和Teacher復用了Person的成員。下面我們使用監(jiān)視窗口查看Student和Teacher對象,可
// 以看到變量的復用。調用Print可以看到成員函數的復用。
class Student : public Person
{
protected:
 int _stuid; // 學號
};
class Teacher : public Person
{
protected:
 int _jobid; // 工號
};

1、2 繼承的定義

? 在上述代碼中,我們初始了繼承。相信大家都有很多疑惑。繼承定義的格式是什么?都有代表的什么意義呢?我們接著往下看,都會做出解釋。

? 上述代碼中,Person是父類,也稱作基類。Student和Teacher是子類,也稱作派生類。

【C++】繼承(通俗易懂,超級詳細),C++,c++,開發(fā)語言

? 其中,繼承方式不僅僅只有public,還有protected和private繼承。具體如下圖:

【C++】繼承(通俗易懂,超級詳細),C++,c++,開發(fā)語言

? 不同的繼承方式會決定派生類對基類成員的訪問權限。具體我們也可看下表:

【C++】繼承(通俗易懂,超級詳細),C++,c++,開發(fā)語言

? 我們只看上表,似乎不容易記住。但是是有規(guī)律的,通過上述的繼承總結出以下幾點:

  1. 基類private成員在派生類中無論以什么方式繼承都是不可見的。這里的不可見是指基類的私有成員還是被繼承到了派生類對象中,但是語法上限制派生類對象不管在類里面還是類外面都不能去訪問它。
  2. 基類private成員在派生類中是不能被訪問,如果基類成員不想在類外直接被訪問,但需要在派生類中能訪問,就定義為protected??梢钥闯霰Wo成員限定符是因繼承才出現的。
  3. 實際上面的表格我們進行一下總結會發(fā)現,基類的私有成員在子類都是不可見?;惖钠渌蓡T在子類的訪問方式 == Min(成員在基類的訪問限定符,繼承方式),public > protected > private。
  4. 使用關鍵字class時默認的繼承方式是private,使用struct時默認的繼承方式是public,不過最好顯示的寫出繼承方式。
  5. 在實際運用中一般使用都是public繼承,幾乎很少使用protetced/private繼承,也不提倡 使用protetced/private繼承,因為protetced/private繼承下來的成員都只能在派生類的類里 面使用,實際中擴展維護性不強

二、基類和派生類對象賦值轉換

??派生類對象 可以賦值給 基類的對象 / 基類的指針 / 基類的引用。這里有個形象的說法叫切片或者切割。寓意把派生類中父類那部分切來賦值過去。具體如下:

class Person
{
protected:
	string _name; // 姓名
	string _sex;  // 性別
	int	_age;	 // 年齡
};

class Student : public Person
{
public:
	int _No; // 學號
};

int main()
{
	Student sobj;
    
    //注意,以下并不是隱式類型轉換,就是語法支持的
	Person pobj = sobj;
	Person* pp = &sobj;
	Person& rp = sobj;

	return 0;
}

【C++】繼承(通俗易懂,超級詳細),C++,c++,開發(fā)語言

? 我們也可結合調試看其對象,具體如下圖:

【C++】繼承(通俗易懂,超級詳細),C++,c++,開發(fā)語言

? 指針和引用也是如此。指針指向的內容也會對派生類進行切斷,使其指向的成員只包含父類的成員。但是,基類對象不能賦值給派生類對象

? 基類的指針或者引用可以通過強制類型轉換賦值給派生類的指針或者引用。但是必須是基類的指針是指向派生類對象時才是安全的。

三、繼承中的作用域

? 在繼承體系中基類派生類都有獨立的作用域。子類和父類中有同名成員,子類成員將屏蔽父類對同名成員的直接訪問,這種情況叫隱藏,也叫重定義。(在子類成員函數中,可以使用 基類::基類成員 顯示訪問

class Person
{
protected :
    string _name = "小李子"; // 姓名
    int _num = 111; ? // 身份證號
};
class Student : public Person
{
public:
    void Print()
    {
        cout<<" 姓名:"<<_name<< endl;
        cout<<" 身份證號:"<<Person::_num<< endl;
        cout<<" 學號:"<<_num<<endl;
    }
protected:
    int _num = 999; // 學號
};
void Test()
{
     Student s1;
     s1.Print();
};

? 上述代碼就是在調用子類的Print()函數,此時的 _num 是子類中的成員變量。打印父類中的 _num 時,使用的是 基類::基類成員 顯示訪問:Person::_num。

? 需要注意的是如果是成員函數的隱藏,只需要函數名相同就構成隱藏。 我們可結合如下代碼理解:

class A
{
public:
	void fun()
	{
		cout << "func()" << endl;
	}
};
class B : public A
{
public:
	void fun(int i)
	{
		A::fun();
		cout << "func(int i)->" << i << endl;
	}
};
void Test()
{
	B b;
	b.fun(10);
};

? 運行結果如下:

【C++】繼承(通俗易懂,超級詳細),C++,c++,開發(fā)語言

? 我們看到,B中的fun和A中的fun不是構成重載,因為不是在同一作用域。B中的fun和A中的fun構成隱藏,成員函數滿足函數名相同就構成隱藏。

? 通過第一個例子中,Student的_num和Person的_num構成隱藏關系,可以看出這樣代碼雖然能跑,但是非常容易混淆。所以在實際中在繼承體系里面最好不要定義同名的成員。

四、派生類的默認成員函數

? 我們知道一個類會有六個默認成員函數,如下圖:

【C++】繼承(通俗易懂,超級詳細),C++,c++,開發(fā)語言

? 所謂默認,“默認”的意思就是指我們不寫,編譯器會變我們自動生成一個,那么在派生類

中,這幾個成員函數是如何生成的呢?

? ?我們先看如下代碼:

class Person
{
public:
	//Person(const char* name = "peter")
	Person(const char* name= "peter")
		: _name(name)
	{
		cout << "Person()" << endl;
	}

	Person(const Person& p)
		: _name(p._name)
	{
		cout << "Person(const Person& p)" << endl;
	}

	Person& operator=(const Person& p)
	{
		cout << "Person operator=(const Person& p)" << endl;
		if (this != &p)
			_name = p._name;

		return *this;
	}

	~Person()
	{
		cout << "~Person()" << endl;
	}
protected:
	string _name; // 姓名
};

class Student : public Person
{
public:

protected:
	int _num;
};


int main()
{
	Student s1;
	return 0;
}

? 派生類Student中,我們自己并沒有寫任何構造函數?,F在,我們定義了一個?Student 對象s1。此時s1對象會自動調用默認的生成的構造函數和析構函數。我們看如下運行結果:

【C++】繼承(通俗易懂,超級詳細),C++,c++,開發(fā)語言

? ?我們看到,這里調用了基類的構造函數和析構函數!那大概就知道派生類默認生成的構造函數會做哪些事情了:派生類的構造函數必須調用基類的構造函數初始化基類的那一部分成員。如果基類沒有默認的構造函數,則必須在派生類構造函數的初始化列表階段顯示調用

? 那么派生類的默認生成的拷貝構造都會做哪些事情呢?我們看如下代碼:

class Person
{
public:
	//Person(const char* name = "peter")
	Person(const char* name)
		: _name(name)
	{
		cout << "Person()" << endl;
	}

	Person(const Person& p)
		: _name(p._name)
	{
		cout << "Person(const Person& p)" << endl;
	}

	Person& operator=(const Person& p)
	{
		cout << "Person operator=(const Person& p)" << endl;
		if (this != &p)
			_name = p._name;

		return *this;
	}

	~Person()
	{
		cout << "~Person()" << endl;
	}
protected:
	string _name; // 姓名
};

class Student : public Person
{
public:
	Student(const char* name, int num)
		:Person(name) //基類沒有默認構造,必須顯式調用構造函數
		, _num(num)
	{
		cout << "Student()" << endl;
	}
protected:
	int _num;
};


int main()
{
	Student s1("zhagnsan",18);
	Student s2(s1);
	return 0;
}

? 上述代碼中,我們先定義了一個 s1 對象,然后用 s2?對象去調用默認拷貝構造函數,用s1?對象來初始化。我們看如下運行結果:

【C++】繼承(通俗易懂,超級詳細),C++,c++,開發(fā)語言

? ?我們通過上述的運行結果可發(fā)現,派生類的拷貝構造函數必須調用基類的拷貝構造完成基類的拷貝初始化。

? 通過上述的兩個例子測試,我們不難發(fā)現,派生類默認生成的六個構造函數是有一定規(guī)律的,很初學類和對象生成的六個默認構造很相似。這里直接給出大家結論:

  1. ?派生類的構造函數必須調用基類的構造函數初始化基類的那一部分成員。如果基類沒有默認的構造函數,則必須在派生類構造函數的初始化列表階段顯示調用。
  2. ?派生類的拷貝構造函數必須調用基類的拷貝構造完成基類的拷貝初始化。
  3. ?派生類的operator=必須要調用基類的operator=完成基類的復制。
  4. ?派生類的析構函數會在被調用完成后自動調用基類的析構函數清理基類成員。因為這樣才能保證派生類對象先清理派生類成員再清理基類成員的順序。
  5. ?派生類對象初始化先調用基類構造再調派生類構造。
  6. ?派生類對象析構清理先調用派生類析構再調基類的析構。
  7. 因為后續(xù)一些場景析構函數需要構成重寫,重寫的條件之一是函數名相同(這個我們后面會講 解)。那么編譯器會對析構函數名進行特殊處理,處理成destrutor(),所以父類析構函數不加virtual的情況下,子類析構函數和父類析構函數構成隱藏關系。
  8. 在派生類所生成的默認構造,會依然保持原有的在類和對象的功能。

? 這里再強調一下派生類中的析構函數。先看如下代碼:

 ~Student()
 {
     ~Person();
     cout<<"~Student()" <<endl;
 }

? 我們上面的派生類 Student 的析構函數會調用基類的析構函數,但是上面的寫法并不正確。因為基類的析構函數和派生類的析構函數構成了隱藏。怎么名字不同也能構成隱藏?其實真正原因是:由于后面多態(tài)的需要,析構函數名字會統(tǒng)一處理成destructor()

? 當然,我們想要顯式調用時,我們可以使用:Person::~Person()。其實我們也不需要自己去調用基類的析構,每個子類析構函數后面,會自動調用父類析構函數,這樣才能保證先析構子類,再析構父類

五、繼承與友元

??友元關系不能繼承,也就是說基類友元不能訪問子類私有和保護成員。如下代碼:

class Student;
class Person
{
public:
	friend void Display(const Person& p, const Student& s);
protected:
	string _name; // 姓名
};
class Student : public Person
{
protected:
	int _stuNum; // 學號
};
void Display(const Person& p, const Student& s)
{
	cout << p._name << endl;
	cout << s._stuNum << endl;
}
void main()
{
	Person p;
	Student s;
	Display(p, s);
}

? 上述代碼是不正確的。有緣并不能繼承,所以 s 對象并不能訪問其保護成員。應在 Student 類中聲明友元函數。正確代碼如下:

class Student;
class Person
{
public:
	friend void Display(const Person& p, const Student& s);
protected:
	string _name="zhangsan"; // 姓名
};

class Student : public Person
{
	friend void Display(const Person& p, const Student& s);
protected:
	int _stuNum=111; // 學號
};

void Display(const Person& p, const Student& s)
{
	cout << p._name << endl;
	cout << s._stuNum << endl;
}

int main()
{
	Person p;
	Student s;
	Display(p, s);
	return 0;
}

六、繼承與靜態(tài)成員

? 基類定義了static靜態(tài)成員,則整個繼承體系里面只有一個這樣的成員。無論派生出多少個子類,都只有一個static成員實例。? 我們看如下代碼:

class Person
{
public:
	Person() { ++_count; }
//protected:
	string _name; // 姓名
public:
	static int _count; // 統(tǒng)計人的個數。
};
int Person::_count = 0;

class Student : public Person
{
protected:
	int _stuNum; // 學號
};

int main()
{
	Person p;
	Student s;

	p._name = "張三";
	cout << s._name << endl;

	cout << Student::_count << endl;
	++Person::_count;
	cout << Student::_count << endl;

	cout << &Person::_count << endl;
	cout << &Student::_count << endl;

	return 0;
}

? 我們在基類中定義了一個 static 變量,該變量可用來統(tǒng)計人數。因為不管是定義派生類對象,還是基類對象,都會調用基類的構造函數。但實例化出來的 _count 只有一份。

七、菱形繼承和菱形虛擬繼承

7、1 單繼承、多繼承和菱形繼承

? 單繼承:一個派生類只能繼承自一個基類,也就是一個子類只有一個直接父類時稱這個繼承關系為單繼承。

【C++】繼承(通俗易懂,超級詳細),C++,c++,開發(fā)語言

? 單繼承的主要特點和優(yōu)點包括:

  • 簡單清晰:派生類與基類之間的關系清晰明確,代碼易于理解和維護。
  • 避免二義性:沒有多個基類之間的成員重名問題,因此避免了成員函數和變量的二義性。
  • 對象模型簡單:派生類對象的內存布局也相對簡單,只需要按照繼承層次從上到下進行構造和析構。

? 多繼承:一個派生類可以同時繼承自多個基類,也就是一個子類有兩個或以上直接父類時稱這個繼承關系為多繼承。

【C++】繼承(通俗易懂,超級詳細),C++,c++,開發(fā)語言

? 多繼承的使用需謹慎,因為它可能引發(fā)一些問題:

  • 成員二義性:當派生類直接或間接地從多個基類繼承相同的成員函數或變量時,容易引發(fā)二義性問題。需要通過作用域解析運算符(::)來指明具體的繼承類。
  • 破壞封裝性:多繼承可能導致類的設計變得復雜,增加模塊之間的耦合性并破壞封裝性。

? 菱形繼承:菱形繼承是多繼承中的一種特殊情況,指派生類同時繼承自兩個或更多個基類,并且這些基類之間存在共同的基類。?

【C++】繼承(通俗易懂,超級詳細),C++,c++,開發(fā)語言

7、2 菱形繼承存在的問題

? 我們首先看如下一段代碼:

class Person
{
public:
	string _name; // 姓名
};

class Student : public Person
{
protected:
	int _num; //學號
};

class Teacher : public Person
{
protected:
	int _id; // 職工編號
};

class Assistant : public Student, public Teacher
{
protected:
	string _majorCourse; // 主修課程
};

int main()
{
	Assistant at;

	// 菱形繼承的二義性問題
	// 數據冗余
	//at._name = "張三";
	at.Student::_name = "張三";
	at.Teacher::_name = "李四";
 
	return 0;
}

? ?我們看到,上述代碼就是一個菱形繼承。實際上,Assistant對象的結構就是如下圖:

【C++】繼承(通俗易懂,超級詳細),C++,c++,開發(fā)語言

? ?我們通過調試也很容易觀察出其結構,如下圖:

【C++】繼承(通俗易懂,超級詳細),C++,c++,開發(fā)語言

? 我們不難從上述結構中發(fā)現,Assistant對象成員模型構造,可以看出菱形繼承有數據冗余和二義性的問題。 在Assistant的對象中Person成員會有兩份。同時還有數據冗余的問題。

? 當然,我們訪問 _name 成員變量時,需要顯示指定訪問哪個父類的成員可以解決二義性問題,但是數據冗余問題無法解決。

? 針對上述問題,我們這里引出菱形虛擬繼承。

7、3 菱形虛擬繼承

7、3、1?菱形虛擬繼承的認識

? 在菱形虛擬繼承中,派生類通過 virtual 關鍵字聲明對基類的繼承關系。我們先看一份代碼:

class Person
{
public:
	string _name; // 姓名
};

class Student : virtual public Person
{
protected:
	int _num; //學號
};

class Teacher : virtual public Person
{
protected:
	int _id; // 職工編號
};

class Assistant : public Student, public Teacher
{
protected:
	string _majorCourse; // 主修課程
};

int main()
{
	Assistant at;

	// 菱形虛擬繼承解決了二義性和數據冗余
	at._name = "小張";
	at.Student::_name = "張三";
	at.Teacher::_name = "李四";

	return 0;
}

? 上述就是菱形虛擬繼承。在上述代碼中,類Student和類Teacher使用virtual關鍵字進行了虛繼承,這樣類Assistant繼承自Student和類Teacher時,只會包含一份類Person的成員變量。我們再通過調試觀察一下,如下:

【C++】繼承(通俗易懂,超級詳細),C++,c++,開發(fā)語言

??虛擬繼承解決了菱形繼承中存在的二義性問題,并減少了資源的重復使用。但需要注意,虛擬繼承會引入虛基表(vtable)以及虛基表指針(vpointer)等額外的開銷。我們在下面講解菱形虛擬繼承的原理中會講到虛基表和虛基表指針。

7、3、2?菱形虛擬繼承的實現原理

? 注:以下測試環(huán)境位vs2019。

? 我們想要搞懂菱形虛擬繼承的實現原理,少不了去了解他在內存中的存儲結構是怎么樣的。為了清晰的觀察,我們采用下面的代碼進行調試:

class A
{
public:
	int _a;
};

class B : virtual public A
{
public:
	int _b;
};

class C : virtual public A
{
public:
	int _c;
};

class D : public B, public C
{
public:
	int _d;
};

int main()
{
	D d;
	d.B::_a = 1;
	d.C::_a = 2;
	d._a = 0;
	d._b = 3;
	d._c = 4;
	d._d = 5;

	return 0;
}

? 我們通過調試,看數據和內存如下圖:

【C++】繼承(通俗易懂,超級詳細),C++,c++,開發(fā)語言

? 通過內存我們發(fā)現,類 B 和類 C 中不在存儲A對象,而是把A對象放到了D對象組的最底下。類 B 和類 C中多出來的值是什么呢?好像是一段地址,我們不妨看看。如下圖:

【C++】繼承(通俗易懂,超級詳細),C++,c++,開發(fā)語言

? 我們把上述的十六進制轉換為十進制后,發(fā)現一個是20,一個是14。其實我們對比不難發(fā)現,這個就是偏移量。該指針就是虛基表指針,指向的就是虛基表。虛基表中存儲的就有偏移量。我們通過虛基表指針,再加上虛基表中所存儲的偏移量,就可以輕松的找到A對象。

? 通過剖析完菱形虛擬繼承在內存中的存儲結構后,我們對菱形虛擬繼承會有一個更加清楚的認知。會對第一個菱形虛擬繼承例子有一個更加清楚的結構認識,如下圖:

【C++】繼承(通俗易懂,超級詳細),C++,c++,開發(fā)語言

八、繼承的總結和反思

? 對繼承的總結如下:
  1. 很多人說C++語法復雜,其實多繼承就是一個體現。有了多繼承,就存在菱形繼承,有了菱形繼承就有菱形虛擬繼承,底層實現就很復雜。所以一般不建議設計出多繼承,一定不要設 計出菱形繼承。否則在復雜度及性能上都有問題。
  2. 多繼承可以認為是C++的缺陷之一,很多后來的語言都沒有多繼承,如Java。

??繼承和組合

  • 組合是另一種代碼復用機制,它描述了對象之間的整體與部分的關系。在組合關系中,一個類(稱為容器類)包含另一個類的對象(稱為成員對象),并且容器類可以通過成員對象來調用其方法和訪問其屬性。
  • 繼承可以實現類之間的"is-a"關系,即派生類是基類的一種特殊類型。通過繼承,可以實現代碼重用、多態(tài)性和層次結構等特性。
  • 通過組合,可以實現類之間的"has-a"關系,即容器類具有成員對象作為其一部分。組合提供了更大的靈活性,因為可以在運行時動態(tài)地更改成員對象。
  • 優(yōu)先使用對象組合,而不是類繼承。
  • 繼承允許你根據基類的實現來定義派生類的實現。這種通過生成派生類的復用通常被稱為白箱復用(white-box reuse)。術語“白箱”是相對可視性而言:在繼承方式中,基類的內部細節(jié)對子類可見 。繼承一定程度破壞了基類的封裝,基類的改變,對派生類有很大的影響。派生類和基類間的依賴關系很強,耦合度高。
  • 對象組合是類繼承之外的另一種復用選擇。新的更復雜的功能可以通過組裝或組合對象來獲得。對象組合要求被組合的對象具有良好定義的接口。這種復用風格被稱為黑箱復用(black-box reuse),因為對象的內部細節(jié)是不可見的。對象只以“黑箱”的形式出現。組合類之間沒有很強的依賴關系,耦合度低。優(yōu)先使用對象組合有助于你保持每個類被封裝。
  • 實際盡量多去用組合。組合的耦合度低,代碼維護性好。不過繼承也有用武之地的,有些關系就適合繼承那就用繼承,另外要實現多態(tài),也必須要繼承。類之間的關系可以用繼承,可以用組合,就用組合。

? 我們也可結合如下代碼一起理解上述概念:

// Car和BMW Car和Benz構成is-a的關系
class Car {
protected:
	string _colour = "白色"; // 顏色
	string _num = "陜ABIT00"; // 車牌號
};

class BMW : public Car {
public:
	void Drive() { cout << "好開-操控" << endl; }
};

class Benz : public Car {
public:
	void Drive() { cout << "好坐-舒適" << endl; }
};

// Tire和Car構成has-a的關系

class Tire {
protected:
	string _brand = "Michelin"; ?// 品牌
	size_t _size = 17; ? ? ? ? // 尺寸

};

class Car {
protected:
	string _colour = "白色"; // 顏色
	string _num = "陜ABIT00"; // 車牌號
	Tire _t; // 輪胎
};

九、總結

? 繼承是C++一個重要特性之一。我們因該熟知繼承的概念,并且熟練的掌握繼承的用法。相對其它語言,C++的繼承想對復雜,但是我們也應該多練,達到孰能生巧的地步。

? 本篇文章的講解就到這里,感謝閱讀ovo~?文章來源地址http://www.zghlxwxcb.cn/news/detail-596762.html

到了這里,關于【C++】繼承(通俗易懂,超級詳細)的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • TypeScript - 泛型 Generics(通俗易懂詳細教程)

    TypeScript - 泛型 Generics(通俗易懂詳細教程)

    關于概念,本文不會過多敘述。 先來看個例子,體會一下泛型解決的問題吧。 我們定義一個 print 函數,這個函數的功能是把傳入的參數打印出來,最后再返回這個參數,傳入參數的類型是 string ,函數返回類型為 string 。 假如現在需求變了,我還需要打印 number 類型,請問怎

    2023年04月15日
    瀏覽(32)
  • C語言malloc函數詳解(通俗易懂)

    簡單來說,malloc函數的作用是開辟一個空間來給你使用; 他包含在標準庫中 返回值是一個void*(可以簡單理解為一個沒人知道它是什么類型的指針),一般我們都要對結果進行類型轉換; 我們通過malloc申請的空間是以字節(jié)為單位的,如malloc(1*1024*1024)則申請了1MB的空間; 如果

    2023年04月08日
    瀏覽(23)
  • Android Studio入門級教程(詳細)【小白必看】[通俗易懂]

    Android Studio入門級教程(詳細)【小白必看】[通俗易懂]

    Android Studio如何使用 本文主要講解一下Android Studio使用方法 步驟: 1.建立項目 首先點擊new——new project新建項目 選擇想要創(chuàng)建的Android 的模板,建議選擇empty activity(空模板),然后next Name:給你的項目起一個名字 API level:選擇Android 虛擬機的版本,版本越低運行起來越快 剩

    2024年02月08日
    瀏覽(26)
  • 回溯法解01背包問題(最通俗易懂,附C++代碼)

    回溯法解01背包問題(最通俗易懂,附C++代碼)

    01背包問題是算法中的經典問題,問題描述如下: 對于給定的N個物品,第i個物品的重量為Wi,價值為Vi,對于一個最多能裝重量C的背包,應該如何選擇放入包中的物品,使得包中物品的總價值最大? 回溯法的本質其實就是一種蠻力法,只是通過一定的方法可以使得蠻力法中

    2023年04月08日
    瀏覽(26)
  • 超級詳細易懂的GhostNet解析

    超級詳細易懂的GhostNet解析

    CVPR2020 IJCV2022(the extended version) Noah’s Ark Lab, Huawei Technologies 論文地址: https://arxiv.org/abs/1911.11907 源碼:https://github.com/huawei-noah/ghostnet. 由于內存和計算資源有限,在嵌入式設備上部署卷積神經網絡(CNNs)是很困難的。特征圖中的冗余性是這些成功cnn的一個重要特征,但在神經結

    2024年02月06日
    瀏覽(16)
  • C++ | 深入淺出類的封裝思想【圖文案例,通俗易懂】

    C++ | 深入淺出類的封裝思想【圖文案例,通俗易懂】

    從本文開始,我們就要正式來學習C++中的類和對象了,本文我將帶你一步步 從C語言的結構體 struct 到C++的類 class ,真正搞懂有關C++的 面向對象的三大特征之一 —— 封裝 作為讀者,可能你正在學習C語言,亦或者已經開始學習C++了,也有可能你是一位C++的資深開發(fā)者或者其他

    2023年04月21日
    瀏覽(23)
  • 通俗易懂的知識蒸餾 Knowledge Distillation(下)——代碼實踐(附詳細注釋)

    第一步:導入所需要的包 第二步:定義教師模型 教師模型網絡結構(此處僅舉一個例子):卷積層-卷積層-dropout-dropout-全連接層-全連接層 第三步:定義訓練教師模型方法 正常的定義一個神經網絡模型 第四步:定義教師模型測試方法 正常的定義一個神經網絡模型 第五步:

    2024年02月12日
    瀏覽(21)
  • 兩百行C++代碼實現yolov5車輛計數部署(通俗易懂版)

    兩百行C++代碼實現yolov5車輛計數部署(通俗易懂版)

    本文是文章傳統(tǒng)圖像處理方法實現車輛計數的后續(xù)。這里用OpenCV實現了基于yolov5檢測器的單向車輛計數功能,方法是撞線計數。該代碼只能演示視頻demo效果,一些功能未完善,離實際工程應用還有距離。 實現流程: (1)訓練yolov5模型,這里就沒有自己訓練了,直接使用官方

    2024年02月06日
    瀏覽(24)
  • 【C語言鏈表實現】學生成績管理系統(tǒng)(功能全面,通俗易懂)

    【C語言鏈表實現】學生成績管理系統(tǒng)(功能全面,通俗易懂)

    題目 :學生成績管理程序 要求 :本程序用于教學單位(院/系)的學生成績管理。要求程序能夠實現學生信息錄入(可以實現增加、刪除、修改學生的基本信息)、單科學習成績的錄入;班級內單科成績排名;成績查詢:查詢某個學生的各科成績、統(tǒng)計所有不及格科目超過

    2024年02月09日
    瀏覽(18)
  • 輕松掌握Docker!最新超詳細版通俗易懂教程,讓你快速成為容器化大師!

    輕松掌握Docker!最新超詳細版通俗易懂教程,讓你快速成為容器化大師!

    注意,安裝社區(qū)版,先看上圖,標記的部分,需要centos7版本以上的;也就是內核版本,必須是3.10及以上,可以通過uname -r命令檢查內核版本 也可以通過查看版本確認是否安裝 docker --version 主機上的圖像,容器,卷或自定義配置文件不會自動刪除。要刪除所有圖像,容器和卷

    2024年01月23日
    瀏覽(51)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包