【C++grammar】繼承與構造

目錄

  • 1.繼承
    • 1、Inheritance (繼承)
    • 2、避免一個類被繼承( C++11 )
    • 3、繼承實例
    • 4、完整代碼
    • 5、繼承的優缺點是什么?
  • 2.繼承中的構造函數
    • 1、 派生類繼承的成員
    • 2、調用基類構造函數
  • 3.繼承中的默認構造函數
    • 1、基類的無參構造函數
    • 2、由編譯器自動生成的基類構造函數會不會被派生類繼承?
  • 4. 構造鏈和析構鏈
    • 1、構造函數鏈
    • 2、析構函數鏈
    • 3、例1
    • 4、例2
    • 5、調用所有的構造函數和析構函數

1.繼承

1、Inheritance (繼承)

在這里插入圖片描述
在這里插入圖片描述

2、避免一個類被繼承( C++11 )

class B final {};
class D : public B {};

編譯后的輸出是 (Visual Studio)
error C3246: “D”: 無法從“B”繼承,因為它已被聲明為“final”這是程序輸出

3、繼承實例

在這里插入圖片描述

1、創建rectangle類、Circle類,從shape類繼承。

class Rectangle : public Shape {......};
class Circle: public Shape {......};

2、使用基類的構造函數初始化基類的數據成員
繼承之后,rectangle也獲得了shape的屬性和方法,這里修改rectangle類的有參初始化函數,同時也對繼承過來的基類數據成員進行初始化。

Circle::Circle(double radius_, Color color_, bool filled_) : Shape{color_,filled_} {radius = radius_;
}
Rectangle::Rectangle(double w, double h, Color color_, bool filled_) :width{ w }, height{h}, Shape{ color_,filled_ } {}

4、完整代碼

繼承與構造test1代碼附錄

5、繼承的優缺點是什么?

繼承方便程序員使用他人寫好的類來實現自己的功能,而不用重復造輪子。
壞處是有時繼承過程中會繼承到許多無用的信息,而且增加了程序的復雜性,容易出錯。

2.繼承中的構造函數

1、 派生類繼承的成員

C++11:派生類不繼承的特殊函數:

(1) 析構函數
(2) 友元函數

繼承基類構造函數:

(1) using A::A; 繼承所有基類ctor
(2) 不能僅繼承指定的某個基類ctor

調用繼承的構造函數

struct A { // 等價于 class A { public:A(int i) {}A(double d, int i) {}// ...
};struct B : A {  // C++11using A::A; // 繼承基類所有構造函數int d{ 0 };   // 就地初始化
};int main() {B b(1);   // 調A(int i)
}

2、調用基類構造函數

若派生類成員也需要初始化,則可以在派生類構造函數中調用基類構造函數。
調用次序:
先調用基類構造函數,再調用內嵌對象構造函數,最后再執行函數體

#include<iostream>
using std::cout;
using std::endl;//task1:繼承構造函數
//創建基類B及構造函數B(int),B(char)和派生類D;
//D中不繼承/繼承B的ctor時的效果。//task2:派生類中調用基類構造函數
//D中增加成員double x;及D(double),在D(double)初始化列表調用B(i)并初始化x//task3:派生類先調用基類ctor,再構造內嵌對象
//增加類E及E(int) ,并在D中加入E的兩個對象;創建D對象觀察E ctor和B ctor 次序class B {
public:B() { cout << "B()" << endl; }B(int i) { cout << "B("<< i << ")" << endl; }B(char c) { cout << "B(" << c << ")" << endl; }
};
class E {
public:E() { cout << "E()" << endl; }
};//D里面沒有構造函數,所以編譯器會自動生成一個默認構造函數,去調用基類的默認構造函數
class D :public B {
private://double x{ 0.0 };E e1, e2;
public://繼承構造函數using B::B;D() = default;	//顯示聲明//D(int i):B(i){}//D(char c):B(c){}//先調用基類構造函數,再調用內嵌對象構造函數,最后再執行函數體D(double x) :e1{}, e2{}, B(static_cast<int>(x)){ cout << "D(" << x << ")" << endl;}
};int main()
{B b;D d;D d2{3.02};
}

當程序員在派生類構造函數中顯式調用基類構造函數時,應將被調用基類構造函數放在派生類構造函數初始化列表中。

3.繼承中的默認構造函數

1、基類的無參構造函數

若基類ctor未被顯式調用,基類的默認構造函數就會被調用。
所以這種繼承的,一定要小心地書寫基類的默認構造函數。
在這里插入圖片描述

2、由編譯器自動生成的基類構造函數會不會被派生類繼承?

class A {};
class B: public A {
public:using A::A;
}

編譯器為基類生成的默認構造函數會不會被繼承到類B中?
在B中提供有參構造函數使編譯器不生成默認構造函數,這段代碼可以執行成功。所以在沒有其他機制的情況下,暫且認為編譯器生成的A類默認構造函數被B類繼承了。
C++編譯器生成默認的構造函數的幾種情況

4. 構造鏈和析構鏈

1、構造函數鏈

構造類實例會沿著繼承鏈調用所有的基類ctor。
調用次序: base first, derive next (父先子后)。

2、析構函數鏈

dtor與ctor正好相反。
調用次序: derive first, base next (子先父后)

3、例1

任務1:創建類結構:Computer->PC->Desktop/Laptop以及相應的ctor/dtor
main中創建Desktop/Laptop的對象,觀察ctor/dtor調用次序

#include <iostream>
using std::cout;
using std::endl;//任務1:創建類結構:Computer->PC->Desktop/Laptop以及相應的ctor/dtor
//	main中創建Desktop/Laptop的對象,觀察ctor/dtor調用次序
class Computer {
public:Computer() { cout << "Computer()" << endl; }~Computer() { cout << "~Computer()" << endl; }
};
class PC : public Computer {
public:PC() { cout << "PC()" << endl; }~PC() { cout << "~PC()" << endl; }
};class Desktop : public PC {
public:Desktop() { cout << "Desktop()" << endl; }~Desktop() { cout << "~Desktop()" << endl; }
};class Laptop : public PC {
public:Laptop() { cout << "Laptop()" << endl; }~Laptop() { cout << "~Laptop()" << endl; }
};
int main()
{Desktop d();Laptop l();return 0;
}

效果:
在這里插入圖片描述

4、例2

任務2:增加類Camera作為Laptop的內嵌對象c的類型
main中創建Laptop對象,觀察內嵌對象c的構造與基類構造次序

#include <iostream>
using std::cout;
using std::endl;
//任務2:增加類Camera作為Laptop的內嵌對象c的類型
// main中創建Laptop對象,觀察內嵌對象c的構造與基類構造次序class Computer {
public:Computer() { cout << "Computer()" << endl; }~Computer() { cout << "~Computer()" << endl; }
};
class PC : public Computer {
public:PC() { cout << "PC()" << endl; }~PC() { cout << "~PC()" << endl; }
};class Desktop : public PC {
public:Desktop() { cout << "Desktop()" << endl; }~Desktop() { cout << "~Desktop()" << endl; }
};
class Camera {
public:Camera() { cout << "Camera()" << endl; }~Camera() { cout << "~Camera()" << endl; }
};
class Laptop : public PC {
private:Camera c{};
public:Laptop() { cout << "Laptop()" << endl; }~Laptop() { cout << "~Laptop()" << endl; }
};
int main()
{Desktop d{};Laptop l{};return 0;
}

效果:
在這里插入圖片描述
構造過程:在祖先類的構造函數執行完后,執行內嵌對象的構造函數,最后執行自己的構造函數。
析構過程:與繼承鏈相反。

5、調用所有的構造函數和析構函數

我們知道,一個類可能有不止一個構造函數。
那么,能否寫出一個例子,創建一個派生類對象,從而把單繼承鏈(鏈無分支)上的所有類的所有構造函數和析構函數都調一遍?
使用代理構造:【C++grammar】代理構造、不可變對象、靜態成員

#include <iostream>
using std::cout;
using std::endl;
class A {
public:A() : A(0) { cout << "A()" << endl; }A(int i) : A(i, 0) { cout << "A(int i)" << endl; }A(int i, int j) {num1 = i;num2 = j;average = (num1 + num2) / 2;cout << "A(int i, int j)" << endl;}
private:int num1;int num2;int average;
};
class A_child : public A {
public:A_child() { cout << "A_child()" << endl; }~A_child() { cout << "~A_child()" << endl; }
};
int main()
{A_child l{};return 0;
}

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/377752.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/377752.shtml
英文地址,請注明出處:http://en.pswp.cn/news/377752.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C語言預處理

所謂預處理是指在進行編譯的第一遍掃描(詞法掃描和語法分析)之前所作的工作。預處理是&#xff23;語言的一個重要功能&#xff0c; 它由預處理程序負責完成。當對一個源文件進行編譯時&#xff0c; 系統將自動引用預處理程序對源程序中的預處理部分作處理&#xff0c; 處理完畢…

(轉)將cocos2dx項目從VS移植到Eclipse

本文轉自:http://www.cnblogs.com/Z-XML/p/3349518.html 引言&#xff1a;我們使用cocos2d-x引擎制作了一款飛行射擊游戲&#xff0c;其中創新性地融入了手勢識別功能。但是我們在移植過程中遇到了很多的問題&#xff0c;同時也發現網上的資料少而不全。所以在項目行將結束的時…

十二、聚類算法——相似度測量

兩套學習資料都類似&#xff0c;可參考聚類算法實戰 一、聚類 聚類&#xff1a;物以類聚&#xff0c;人以群分&#xff0c;是無監督學習中的一種。 沒有y&#xff0c;只有x&#xff0c;把不同的x根據相似度自動的聚成好多堆兒 本質上&#xff0c;N個樣本&#xff0c;映射到K個…

操作系統磁盤調度_磁盤調度| 操作系統

操作系統磁盤調度磁盤調度 (Disk Scheduling) One of the major duties of the operating is that, to use the hardware orderly and accurately. For disk drives, it has a duty of having a fast access time and disk bandwidth. Generally, bandwidth is the total numbe…

leetcode 344. 反轉字符串 541. 反轉字符串 II 雙指針解

目錄leetcode 344.反轉字符串1、題目2、思考leetcode 541. 反轉字符串 II1、題目2、思考leetcode 344.反轉字符串 1、題目 2、思考 典型的雙指針解法&#xff1a; 一個從前往后&#xff0c;一個從后往前&#xff0c;指針對應的交換即可。 class Solution { public:void reve…

關于銀聯在線支付和短彩信接口的開發——總結

9月份開始做用二維碼做閉環的一個在線訂購景區門票的項目&#xff0c;其中這樣做是很好的&#xff0c;用二維碼連接了線上與線下的交易和兌券。銀聯在線支付接口&#xff08;asp.net cs&#xff09;做的很好&#xff0c;方便調用開發。就是處理回值的時候得找個更好的方法才能顯…

十三、聚類算法

六、聚類算法實戰 一、聚類 聚類是一種無監督的機器學習任務&#xff0c;可以自動將數據劃分為類cluster&#xff0c;因此聚類分組不需要提前被告知所劃分的組應該是什么樣子的。因為我們甚至可能都不知道我們在尋找什么&#xff0c;所以聚類是用于知識發現而不是預測。 聚類…

pl/sql中的賦值運算符_如何在SQL中使用AND / OR運算符?

pl/sql中的賦值運算符Basically, AND / OR operator is used to retrieving the record from the database. If we give more than one conditions by using AND Operator, then it retrieves the data from the database when both the conditions are true. And if we use OR…

【C++grammar】名字隱藏與重定義

目錄1、繼承中的名字隱藏1.基類同名函數被隱藏的現象描述2.問題理解3.避免現象2、重定義1.現象描述2.重定義與重載的區別3.能否使用 using 將基類成員引入到派生類定義中1、繼承中的名字隱藏 1.基類同名函數被隱藏的現象描述 在學習變量作用域的時候知道&#xff0c;全局變量…

javascript 核心概念(1)-數據類型

語法 &#xff08;1&#xff09;到現在為止&#xff0c;大多數瀏覽器也還是支持到ECMAScript 第三版的標準。 核心概念就是一個語言的基本工作原理&#xff0c;涉及語法&#xff0c;操作符&#xff0c;數據類型。 &#xff08;2&#xff09;javascript的一切--變量&#xff0c;…

注解的力量 -----Spring 2.5 JPA hibernate 使用方法的點滴整理(五):使用@Component 來簡化bean的配置...

雖然我們可以通過 Autowired 在 Bean 類中使用自動注入功能&#xff0c;但是 Bean 還是在 applicatonContext.xml 文件中通過 <bean> 進行定義 —— 在前面的例子中&#xff0c;我們還是在配置文件中定義 Bean&#xff0c;通過 Autowired為 Bean 的成員變量、方法形參或構…

c語言條件語句示例_PHP中的條件語句和示例

c語言條件語句示例PHP條件語句 (PHP Conditional Statements) While coding, you may get to a point where your results can only be gotten when a condition is valid. We make use of conditional statements. Conditional statements are statements that can only be ex…

十四、聚類實戰——圖片壓縮

對同一像素點值的像素點歸為一類&#xff0c;通過平均值進行取代&#xff0c;從而將圖像進行壓縮并且保證圖像盡可能不失真&#xff0c;關鍵信息仍保留。 from PIL import Image import numpy as np from sklearn.cluster import KMeans import matplotlib import matplotlib.…

步驟菜單使用css3實現

代碼庫&#xff1a;http://thecodeplayer.com/walkthrough/css3-breadcrumb-navigation 有興趣的可以看一下&#xff0c;看完絕對讓你大飽眼福。首先截圖&#xff0c;看效果看著很酷吧&#xff0c;其實實現起來也不是很難&#xff0c;里邊需要用的技術有:box-shadow,計數器&…

【嵌入式系統】STM32串口通信的四種方法(基于RTOS)

目錄1、串行通信的基本參數2、輪詢方式代碼效果3、中斷方式代碼效果4、中斷加上時間戳方式代碼及效果5、DMA空閑中斷方式接收數據1、串行通信的基本參數 串行端口的通信方式是將字節拆分成一個接一個的位再傳輸出去&#xff0c;接收方再將此一個一個的位組合成原來的字符&…

大數據 java 代碼示例_Java變量類型與示例

大數據 java 代碼示例Java變量 (Java variables) Variables are the user-defined names of the memory blocks, and their values can be changed at any time during program execution. They play an important role in a class/program as they help in to store, retrieve…

畢業設計

位置跟蹤系統工作原理&#xff08;博聞網&#xff09; http://science.bowenwang.com.cn/location-tracking.htm Azuma是這樣定義增強現實的 :虛實結合 ,實時交互 ,三維注冊 環境搭建&#xff1a; http://cvchina.net/thread-173-1-1.html http://blog.csdn.net/jdh99/article/…

十五、聚類的評估

一、Given Label 均一性homogeneity&#xff1a;一個簇中只包含一個類別樣本&#xff0c;Precision 完整性completeness&#xff1a;同類別樣本被歸到同一個簇中&#xff0c;Recall 將均一性h和完整性c進行結合(二者加權平均)得到V-Measure&#xff0c;&#xff0c;β為權重 …

SQL SERVER作業的Schedules淺析

SQL SERVER作業的計劃&#xff08;Schedules&#xff09;&#xff0c;如果你沒仔細研究過或沒有應用一些復雜的計劃&#xff08;Schedules&#xff09;&#xff0c;那么你覺得SQL SERVER作業的計劃(Schedules)非常好用&#xff0c;也沒啥問題&#xff0c;但是我要告訴你一個“殘…

leetcode 51. N 皇后 思考分析

目錄題目思考AC代碼題目 n 皇后問題研究的是如何將 n 個皇后放置在 nn 的棋盤上&#xff0c;并且使皇后彼此之間不能相互攻擊。 思考 首先以N4為例&#xff0c;畫出解空間樹的一部分&#xff1a; 根據模板&#xff1a; void backtracking(參數) {if(終止條件){存放結果…