GCC-3.4.6源代碼學習筆記

大約4年前,我加入了GDNT - 北電網絡在中國的合資企業,參與3G UMTS無線接入網的研發工作。與GCC有了第一次親密的接觸(之前使用的是MS的VC)。彼時,北電在其諸如,UMTS、CDMA、及自行開發的眾多工具等項目中(此后,在4G項目,Wimax及Lte中),將GCC作為標準編譯器來使用。每周我都需要進行數次的loadbuild,編譯出load文件進行測試,以驗證我對一些bug的修正代碼。每次loadbuild,編譯的文件數以千計,最后的執行文件可至百兆的尺寸。而GCC的運行令人驚異地穩定。這些年來,我只碰到過2次GCC的崩潰,其中一次還是因為我為了達到模板分離編譯(separate compilation of template)的效果(GCC至今未支持這一特性。據我所知,目前只有EDG的前端能做到。而且在C++標準穩定下來之前【ISO-IEC - 14882-1998】,EDG的前端是實際的標準。在http://www.edg.com/可以找到有關EDG的情況),使用了奇怪的代碼(含有錯誤的C++代碼),而導致生成錯誤的中間樹代碼(很遺憾,GCC未能檢出語法錯誤)。從而觸發了GCC內部的斷言。因此GCC雖然退出,但給出了詳細的錯誤轉儲。還算退出得比較體面。

這個神奇的工具令人稱奇!雖然以前我也學過編譯原理,但是面對GCC,我覺得對它知之甚少。多虧GCC是開源的,使我得以窺探其神秘面紗后的容顏。這些年,雖然自覺對GCC已有相當的了解,但遠還未到究竟。借此博客,我將和大家分享這些年來學習GCC的筆記(所關注的GCC為:3.4.6版,C++前端,運行平臺:x86/Linux,目標機器:x86/Linux)。而這個筆記還在增長中,還遠未結束。

參考文獻

[1] Programming language pragmatics, 2nd edition

[2] gccint, version 3.4.6

[3] ISO-IEC-14882-2003

[4] The C Preprocessor April 2001, for GCC V3

[5] cppinternals

[6] Using the GNU Compiler Collection

[7] Inside The C++ Object Model, by Stanley B.Lippman

[8] GCC Complete Reference

[9] The design and evolution of C++, by Bjarne Stroustrup

[10] Linkers & Loaders, by John R. Levine

[11] Efficient Instruction Scheduling Using Finite State Automata, by Vasanth Bala, Norman Rubin

[12] Compilers: Principles, Techniques, and Tools, 2nd edition

其中,[2]和[5]保存在目錄“YOUR-GCC-SOURCE-DIR/gcc/doc”下。[1],[7],[9],[10]和[12]給出了一些有用的背景知識。

準備工作

一些重要的GCC源碼是由GCC自帶工具生成的。在深入看代碼前,我們首先需要編譯GCC,生成這些源碼。至于如何下載源代碼(http://gcc.gnu.org/mirrors.html是官方的下載地址),編譯前配置及編譯,網上有豐富的資料,在此略過(注:如果已經裝有GCC,使用g++ -###可查看GCC的配置命令)。

GCC的架構

GCC可簡單地分為2部分:前端和后端。預處理器(如果存在)、詞法分析器和語法分析器在前端實現,前端的作用是將源語言寫的程序轉換成與語言無關的中間形式。因此,理論上,引入對新語言的支持,只需要實現預處理器、詞法分析器和語法分析器。但實際上,一般的我們還需要寫一些代碼以確立運行時環境。

在GCC 3.4.6,這個通用的中間語言是RTL(register transfer language)。RTL是一種簡單的語言,很容易就能翻譯成匯編代碼。因此,直接將源語言轉換為RTL,不太合適。事實上,前端首先會將代碼轉換成中間樹并進行大量的處理,然后再進一步變換為RTL,并送入后端。

后端的作用則是生成匯編代碼。作為廣泛使用的編譯器,GCC可以支持各種流行的平臺。為了實現這個目的,GCC采用了機器描述文件,對目標機器的指令集、流水線結構、甚至架構本身帶來的優化機會進行描述。對于目標機器(配置GCC時需指定),這些描述文件將被多個工具處理,生成相應的源代碼,然后用于編譯GCC。因此,引入新機器的主要工作,在于提供機器描述文件(一般而言還需要定義一些處理函數提供必要的處理邏輯)。

在以下地址,http://www.ibm.com/developerworks/cn/linux/l-gcc4/?ca=dwcn-newsletter-linux,可以找到關于GCC較新版本的信息。

前端

當我們調用 ”gcc –o xxx xxx.c” 時,事實上我們的請求會轉交給一個shell,這個shell會解析這個調用命令,并根據它所能認識的命令行選項,在所運行的平臺上進行相應的準備。然后根據源文件的后綴,調用相匹配的編譯器,并將其不能識別的命令行選項一并傳入。這里我們不關心這個shell,我們專注于真正的編譯器。

1.????? 概覽

前端讀入源程序進行語法分析,然后將其轉換為語言無關形式。理論上,每個前端可以使用獨特的形式。不過在GCC中,為了盡可能地重用代碼,不同前端生成的中間樹都使用同一組樹節點。顯然,這組節點需要足夠的多樣性以滿足不同語言的要求。這組樹節點對于C/C++前端的意義非同尋常,我們首先需要對其著手。

1.1. 前端中樹的表達形式

為了支持已經存在及以后將會加入的前端,GCC定義了數十種的樹節點(不是所有節點都能作為葉子節點)。所有的節點,在其結構體定義中,以下面的結構作為第一個成員。

?

129? struct tree_common GTY(())??????????????????????????????????????????????????????????????? ????????????? in tree.h

130? {

131? ? tree chain;

132? ? tree type;

133?

134? ? ENUM_BITFIELD(tree_code) code : 8;

135?

136? ? unsigned side_effects_flag : 1;

137? ? unsigned constant_flag : 1;

138? ? unsigned addressable_flag : 1;

139? ? unsigned volatile_flag : 1;

140? ? unsigned readonly_flag : 1;

141? ? unsigned unsigned_flag : 1;

142? ? unsigned asm_written_flag: 1;

143? ? unsigned unused_0 : 1;

144?

145? ? unsigned used_flag : 1;

146? ? unsigned nothrow_flag : 1;

147? ? unsigned static_flag : 1;

148? ? unsigned public_flag : 1;

149? ? unsigned private_flag : 1;

150? ? unsigned protected_flag : 1;

151? ? unsigned deprecated_flag : 1;

152? ? unsigned unused_1 : 1;

153?

154? ? unsigned lang_flag_0 : 1;

155? ? unsigned lang_flag_1 : 1;

156? ? unsigned lang_flag_2 : 1;

157? ? unsigned lang_flag_3 : 1;

158? ? unsigned lang_flag_4 : 1;

159? ? unsigned lang_flag_5 : 1;

160? ? unsigned lang_flag_6 : 1;

161? ? unsigned unused_2 : 1;

162? };

?

上面,在134行,在3.4.6版,ENUM_BITFIELD將被擴展為”__extension__ enum”, 131行的chain,如果需要,能將該節點鏈入樹。

下面給出了,結構體中部分的標識域的含義,及訪問它們的宏定義(紅字部分)。

????????? TREE_TYPE ((NODE)->common.type)

用于所有表示表達式的節點,代表該表達式的數據類型。

2??????? 在POINTER_TYPE節點中,代表該指針指向的類型。

2??????? 在ARRAY_TYPE節點中,代表數組元素的類型。

2??????? 在VECTOR_TYPE節點中,代表vector元素的類型(某些芯片的寄存器足夠大,足以存放多個標量,這一組標量稱為vector類型)。

????????? TREE_ADDRESSABLE((NODE)->common.addressable_flag)

2??????? 在VAR_DECL節點中,非零值表示該節點代表的變量的地址,在程序的其他地方被使用,不能產生將該變量置入寄存器的代碼。

2??????? 在FUNCTION_DECL節點中,非零值表示該節點代表的函數的地址,在程序的其他地方被使用。該函數必須被編譯出來即便它是內聯函數(在被調用的地方,內聯函數被展開為函數體,故不需要單獨編譯出來)。

2??????? 在FIELD_DECL節點中,非零值表示該節點代表的成員的地址允許被程序員設定。彼時,該標識用于別名識別:參見函數record_component_aliases

2??????? 在CONSTRUCTOR節點中,非零值表示該構造函數必須在內存中創建對象(而不是在寄存器中)。

2??????? 在LABEL_DECL節點中,非零值表示一條目標為該lable的goto語句,出現在所有執行跳轉到該label的goto語句,需要恢復棧的綁定域外。

2??????? 在所有*_TYPE節點中,非零值表示該類型的所有對象必須是完全取址的。這意味著,例如:這些對象任何一部分都不能放入寄存器中。

2??????? 在IDENTIFIER_NODE節點中,非零值表示某些同名的外部聲明的地址已被引用。這關系到內聯函數。

????????? TREE_STATIC ((NODE)->common.static_flag)

2??????? 在VAR_DECL節點中,非零值表示該變量為靜態類型。

2??????? 在FUNCTION_DECL節點中,非零值表示該函數已被定義。

2??????? In a CONSTRUCTOR, nonzero means allocate static storage.

????????? TREE_VIA_VIRTUAL ((NODE)->common.static_flag)

2??????? 在TREE_LIST或TREE_VEC節點中,非零值表示所對應的類,其派生關系為虛繼承(virtual)。

????????? TREE_CONSTANT_OVERFLOW ((NODE)->common.static_flag)

2??????? 在INTEGER_CST,REAL_CST,COMPLEX_CST或 VECTOR_CST節點中,非零值表示在常量折疊中發生溢出。它與TREE_OVERFLOW的區別在于,如果常量表達式發生溢出,ANSI C要求給出診斷信息。

????????? TREE_SYMBOL_REFERENCED

(IDENTIFIER_NODE_CHECK (NODE)->common.static_flag)

2??????? 在IDENTIFIER_NODE節點中,非零值表示該字串作為參數調用了函數assemble_name

????????? CLEANUP_EH_ONLY ((NODE)->common.static_flag)

2??????? 在TARGET_EXPR,WITH_CLEANUP_EXPR,CLEANUP_STMT節點,或塊(block)的清理(cleanup)鏈的節點中,非零值表示相關的清理只在異常拋出時執行,而在正常退出時不需要執行。

????????? TREE_OVERFLOW ((NODE)->common.public_flag)

2??????? 在INTEGER_CST,REAL_CST,COMPLEX_CST或VECTOR_CST節點中,非零值表示在常量折疊中發生溢出,并且這部分的警告還沒有發出。TREE_OVERFLOW同時意味著TREE_CONSTANT_OVERFLOW,但反之不成立。

????????? TREE_PUBLIC((NODE)->common.public_flag)

2??????? 在VAR_DECL或FUNCTION_DECL節點中,非零值表示該名字可從模塊(module)外訪問。在IDENTIFIER_NODE節點中,非零值表示在域內(inner scope),已有該名字所代表的,能從模塊(module)外訪問的,外部鏈接性的聲明(external declaration)。

????????? TREE_PRIVATE ((NODE)->common.private_flag)

2??????? 在C++里,在類中使用。

????????? CALL_EXPR_HAS_RETURN_SLOT_ADDR ((NODE)->common.private_flag)

2??????? 在CALL_EXPR節點中,非零值表示返回值的地址是參數鏈的一部分。

????????? TREE_PROTECTED ((NODE)->common.protected_flag)

2??????? 在C++中用于類。在BLOCK節點中,這是個BLOCK_HANDLER_BLOCK節點。

????????? CALL_FROM_THUNK_P ((NODE)->common.protected_flag)

2??????? 在CALL_EXPR節點中,非零值表示該函數調用是從thunk到thunk目標函數的跳轉。

????????? TREE_SIDE_EFFECTS ((NODE)->common.side_effects_flag)

2??????? 在所有的表達式中,非零值表示該表達式含有副作用(side effects)或者對其每次求值(reevaluation of the whole expression)將產生不同的值。如果其子表達式是一個函數調用、對一個volatile變量的引用或含有副作用,這個標識符將被設置。

2??????? In a *_DECL, this is set only if the declaration said `volatile'.

????????? TREE_THIS_VOLATILE ((NODE)->common.volatile_flag)

2??????? 非零值表示該表達式在C的含義下(in the C sense)是volatile:它的地址應該是類型`volatile WHATEVER *'。換而言之,所聲明的項(item)是volatile修飾的(volatile qualified)。該標識符用于*_DECL和*_REF節點中。

2??????? 在*_TYPE節點中,非零值表示其對應的類型為volatile修飾的(volatile-qualified)。不過如果節點代表一個類型,應該使用TYPE_VOLATILE而不是這個宏。因為,以后這2個宏會訪問不同的位(現在是相同的,見下一條)。如果這個位被設上,TREE_SIDE_EFFECTS也應該同時被設上。

????????? TYPE_VOLATILE (TYPE_CHECK (NODE)->common.volatile_flag)

2??????? 非零值表示該類型作為整體是volatile的。

????????? TREE_READONLY ((NODE)->common.readonly_flag)

2??????? 在VAR_DECL,PARM_DECL或者FIELD_DECL,或者所有*_REF類型節點中,非零值表示它不能作為左值(the lhs of an assignment)。

2??????? 在*_TYPE節點中,非零值表示其對應的類型為常量(const-qualified)類型(但是如果節點表示類型則應該使用宏TYPE_READONLY)。

????????? TYPE_READONLY (TYPE_CHECK (NODE)->common.readonly_flag)

2??????? 非零值表示該節點代表的類型為常量類型。

????????? TREE_CONSTANT ((NODE)->common.constant_flag)

2??????? 非零值表示表達式的值為常量。在所有的*_CST節點中設置。也可能出現在數學表達式中,ADDR_EXPR或者CONSTRUCTOR節點中,如果它們的值為常量。

????????? TREE_UNSIGNED ((NODE)->common.unsigned_flag)

2??????? 在INTEGER_TYPE或者ENUMERAL_TYPE節點中,非零值表示其對應類型為無符號類型。在FIELD_DECL節點中,則表示為無符號域(unsigned bit field)。

????????? TREE_ASM_WRITTEN ((NODE)->common.asm_written_flag)

2??????? 在VAR_DECL節點中表示匯編代碼也被寫入。

2??????? 在FUNCTION_DECL節點中表示該函數已被編譯。在內聯函數中,這個位很有意義,因為內聯函數可能不需要獨立編譯(作為函數)。

2??????? 在RECORD_TYPE,UNION_TYPE,QUAL_UNION_TYPE或者ENUMERAL_TYPE節點中,表示有關類型的sdb調試信息已經寫入。

2??????? 在BLOCK節點中,非零值表示在這個分段(block)內,reorder_block節點已發現。

????????? TREE_USED ((NODE)->common.used_flag)

2??????? 在*_DECL節點中表示,在其作用域中,相應的名字被引用(is used in its scope)。

2??????? 在表達式節點中,表示如果其值未被使用,不發出警告。

2??????? 在IDENTIFIER_NODE節點中,表示同名的外部聲明已被引用(was used)。

????????? TREE_NOTHROW ((NODE)->common.nothrow_flag)

2??????? 在FUNCTION_DECL節點中,表示該函數不會拋出異常。在CALL_EXPR節點中,則表示該次調用不會拋出異常。

????????? TYPE_ALIGN_OK (TYPE_CHECK (NODE)->common.nothrow_flag)

2??????? 用在表示類型的節點中,非零值表示所有該類型的對象由語言或前端保證,被正確地對齊。因此,我們可以得知該類型的MEM節點(RTL節點)的對齊量不少于該類型的對齊量,盡管它可能看起來不是這樣。在面向對象語言中,這種情況發生在一個要求更多對齊量量的變種類型的對象上(in object-oriented languages where a tag field may show this is an object of a more-aligned variant of the more generic type)。

????????? TREE_DEPRECATED ((NODE)->common.deprecated_flag)

2??????? 在IDENTIFIER_NODE節點中,該名字的使用是被__attribute__((deprecated))所不推薦的。

列表 1:tree_common中的標識符

1.1.1. 樹節點的定義

以下是中間樹的節點的定義。

?

45??? typedef union tree_node *tree;????????????????????????????????????????????????????????????? in coretypes.h

?

1772 union tree_node GTY ((ptr_alias (union lang_tree_node),????????????????????????????? intree.h

1773?????????????? ????desc ("tree_node_structure (&%h)")))

1774 {

1775 ??struct tree_common GTY ((tag ("TS_COMMON"))) common;

1776 ??struct tree_int_cst GTY ((tag ("TS_INT_CST"))) int_cst;

1777 ??struct tree_real_cst GTY ((tag ("TS_REAL_CST"))) real_cst;

1778 ??struct tree_vector GTY ((tag ("TS_VECTOR"))) vector;

1779 ??struct tree_string GTY ((tag ("TS_STRING"))) string;

1780 ??struct tree_complex GTY ((tag ("TS_COMPLEX"))) complex;

1781 ??struct tree_identifier GTY ((tag ("TS_IDENTIFIER"))) identifier;

1782 ??struct tree_decl GTY ((tag ("TS_DECL"))) decl;

1783 ??struct tree_type GTY ((tag ("TS_TYPE"))) type;

1784 ??struct tree_list GTY ((tag ("TS_LIST"))) list;

1785 ??struct tree_vec GTY ((tag ("TS_VEC"))) vec;

1786 ??struct tree_exp GTY ((tag ("TS_EXP"))) exp;

1787 ??struct tree_block GTY ((tag ("TS_BLOCK"))) block;

1788 };

?

顯然,這個節點需要定義為union。注意第1772行的ptr_alias,它告訴GTY (GCC的廢料回收系統(garbage collection service),我們暫時不理會它),指向tree_node的指針實際上指向lang_tree_node,這個節點由前端通過tree_node追加額外的特定于語言的成員來定義(因此,它可被視為tree_node)。在C++前端中,lang_tree_node有如下定義:

?

472? union lang_tree_node GTY((desc ("cp_tree_node_structure (&%h)"), ??????????? incp-tree.h

473? ?????? chain_next ("(union lang_tree_node *)TREE_CHAIN (&%h.generic)")))

474? {

475? ? union tree_node GTY ((tag ("TS_CP_GENERIC"),

476????????????????????? desc ("tree_node_structure (&%h)"))) generic;

477? ? struct template_parm_index_s GTY ((tag ("TS_CP_TPI"))) tpi;

478? ? struct ptrmem_cst GTY ((tag ("TS_CP_PTRMEM"))) ptrmem;

479? ? struct tree_overload GTY ((tag ("TS_CP_OVERLOAD"))) overload;

480? ? struct tree_baselink GTY ((tag ("TS_CP_BASELINK"))) baselink;

481? ? struct tree_wrapper GTY ((tag ("TS_CP_WRAPPER"))) wrapper;

482? ? struct tree_default_arg GTY ((tag ("TS_CP_DEFAULT_ARG"))) default_arg;

483? ? struct lang_identifier GTY ((tag ("TS_CP_IDENTIFIER"))) identifier;

484? };


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

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

相關文章

互聯網

2019獨角獸企業重金招聘Python工程師標準>>> 轉載于:https://my.oschina.net/u/3127489/blog/1550726

GCC筆記 命令行分析

1984年,Richard Stallman發起了自由軟件運動,GNU (Gnus Not Unix)項目應運而生,3年后,最初版的GCC橫空出世,成為第一款可移植、可優化、支持ANSI C的開源C編譯器。GCC最初的全名是GNU C Compiler,之后,隨著…

java 反射用法_Java 反射的概念與使用

一,反射的概念對于一個人來說,了解自己的能力、本事、特點,對于他去干事創業來說,是很重要的。同樣的,對于一門面向對象的語言來說,了解類(對象其實就是類的實現)本身也是重要的,可以在很多地方…

關于Unity中的Mesh Collider碰撞器

原來我的場景中有一個平面Plane帶Mesh Collider碰撞器組件,一個主角Hero帶有一個Box Collider碰撞器和有重力的Rigidbody剛體組件,主角可以放在平面上。 在導入場景后,隱藏平面Plane,給一個地板添加一個Mesh Collider碰撞器&#…

GCC常用選項使用詳解

通常所說的GCC是GUN Compiler Collection的簡稱,除了編譯程序之外,它還含其他相關工具,所以它能把易于人類使用的高級語言編寫的源代碼構建成計算機能夠直接執行的二進制代碼。GCC是Linux平臺下最常用的編譯程序,它是Linux平臺編譯…

java 井字棋 人機_井字游戲 人機對戰 java實現

package com.ecnu.Main;/*** 主函數觸發游戲*/public class MainApplication {public static void main(String[] args){TicTacToeGame ticTacToeGame new TicTacToeGame();ticTacToeGame.start();}}//TicTacToeGame 方法類import java.util.Scanner;public class TicTacToeGa…

Session(數據)共享的前后端分離Shiro實戰

1,前言本文期望描述如何使用Shiro構建基本的安全登錄和權限驗證。本文實戰場景有如下特殊需求:1,在集群和分布式環境實現session共享;2,前端只使用HTML/CSS/JS。因此無法直接使用Shiro提供的SessionManager&#xff0c…

讀書筆記(javascript 高級程序設計)

一. 數據類型: 1. undefined: 未聲明和未初始化的變量,typeof 操作符返回的結果都是 undefined;(建議未初始化的變量進行顯式賦值,這樣當 typeof 返回 undefined 時就知道是未聲明了,幫助定位問…

關于gcc擴展中的宏定義中用 # 和 ##

關于gcc擴展中的宏定義中用 "#" 和 "##"今天測試了宏定義中的 "#" 和 "##" 的區別。 結果如下: "#" 代表和一個字符串相連接 "##" 代表和一個符號連接,符號可以是變量,或另一…

java 年計算_java實現計算某年某月的天數

在計算某年某月的天數時,需要注意平年閏年。分析:閏年具體的判定方法就要看它的判定條件:四年一閏 , 百年不閏 ,400年再閏。而計算該年該月的天數,又分大月和小月,特殊月份2月之分。(視頻教程推…

添加自定義菜單,報錯40155

2019獨角獸企業重金招聘Python工程師標準>>> 提交的json中,某個自定義菜單對應的URL訪問是有問題的,請挨個檢查一下。 轉載于:https://my.oschina.net/selly1025/blog/1551496

gcc編譯流程及中間表示層RTL的探索

gcc編譯流程及中間表示層RTL的探索收藏新一篇: 解讀VC編程中的文件操作API和CFile類 | 舊一篇: Effective Item21 盡可能使用const 內容摘要 本文將以 C 語言為例,介紹 gcc 在接受一個 .c文件的輸入之后,其前端是如何進行處理并得到一個中間表示并轉交給…

【bzoj2132】圈地計劃 網絡流最小割

題目描述 最近房地產商GDOI(Group of Dumbbells Or Idiots)從NOI(Nuts Old Idiots)手中得到了一塊開發土地。據了解,這塊土地是一塊矩形的區域,可以縱橫劃分為NM塊小區域。GDOI要求將這些區域分為商業區和工業區來開發。根據不同的地形環境,每…

python爬蟲爬取數據如何將br去掉_Python怎么去除爬取下來的網站中的一些轉義字符串 - 收獲啦...

基本方法其實用python爬取網頁很簡單,只有簡單的幾句話這樣就可以獲得到頁面的內容。接下來再用正則匹配去匹配所需要的內容就行了。但是,真正要做起來,就會有各種各樣的細節問題。2.登錄這是一個需要登錄認證的網站。也不太難,只…

Linux基礎

Linux的特點: 系統版本:常見的有debian、Redhat更適合做服務器,更安全和穩定,Ubuntu唯一的優勢就是圖形界面好,centos目前被redhat收購,紅旗已經倒閉。 1、免費的/開源的;2、支持多線程/多用戶&…

GCC的編譯和調試--入門介紹

編譯與調試1.1編譯的概念和理解在進行C程序開發時,編譯就是將編寫的C語言代碼變成可執行程序的過程,這一過程是由編譯器來完成的。編譯器就是完成程序編譯工作的軟件,在進行程序編譯時完成了一系列復雜的過程。1.1.1程序編譯的過程在執行這一…

A* a=new B ,會不會產生內存泄露了,露了B-A的部分?

A* anew B ,delete a;會不會產生內存泄露了,露了B-A的部分。其中B為A的子類 析構函數在下邊3種情況時被調用:1.對象生命周期結束,被銷毀時;2.delete指向對象的指針時,或delete指向對象的基類類型指針,而其基…

spring 第一天:1015

對象加強的三種方法:1/繼承2/裝飾著模式3/動態調用 2:裝飾著模式:就是就是1-先建一個基類 ,如咖啡類 。味道很苦2- 再建一個類配料類 也就是說是所欲配料種類的父類。然后寫多配料子類個子類繼承配料類,。3-子類三個步…

java public 繼承_java繼承問題

代碼:父類:public class Father {public Father() {System.out.println("基類構造函數{");show();new a();System.out.println("}");}public void show() {System.out.println("基類----show");}public class a {public a…

BZOJ 1662: [Usaco2006 Nov]Round Numbers 圓環數(數位DP+惡心細節)

BZOJ 1662: [Usaco2006 Nov]Round Numbers 圓環數 Time Limit: 5 Sec Memory Limit: 64 MBDescription 正如你所知,奶牛們沒有手指以至于不能玩“石頭剪刀布”來任意地決定例如誰先擠奶的順序。她們甚至也不能通過仍硬幣的方式。 所以她們通過"round number&q…