C 學習筆記(三)

2021-07-16 14:20:38 字數 3397 閱讀 7121

啊...這兩天一直在忙活ac自動機和資料庫的東西... c#都沒怎麼看... 今天繼續學習(填坑...)

類成員: readonly可以用於修飾類成員,性質與const差不多但是const是在編譯期間確定,readonly是在執行時確定的。static關鍵字用於指定某個class固有的內容(變數或者方法). get和set我一直理解為c++的那種private成員對應的public getter/setter但是今天終於發現其實理解錯了。例如如下的**

class testclass

}

我一直以為c#會自動生成兩個方法setmyint()和getmyint()但是後來我才發現其實這其實就是相當於myint乙個變數而已。可以在get或set上進行許可權控制比如protected set等等. 也可以細化get與set,在get和set中加入訪問控制或者日誌記錄比如這樣

class testclass

set}

}

此時如果賦給myint的值大於等於10將不會更改realvalue的值。其實還是對私有成員的一定包裝。(順便說visual studio c# 真是貼心... 只要是訪問不到的東西在ide裡面根本看不見(就是那個小的浮動彈出提示視窗) 而c++的ide總是會把private的方法以及變數展示出來... 乾瞪眼不能用...)

類方法: 派生類可以選擇重寫基類提供的方法,前提是這個方法必須是虛方法而且重寫的時候必須加上override ( public override void methodname() ) . override時可以指定sealed. 如果不是virtual方法不能使用override關鍵字,只能使用new關鍵字( new public void methodname() ). 舉個例子

public class baseclass

public void b()

}public class derivedclass : baseclass

new public void b()

}

這裡面derivedclass中的a()因為在基類中是virtual的因而必須使用override進行重寫, 同時由於使用了override, 訪問控制(public)必須和基類方法一致, 返回型別也需要保持一致。另外如果參數列不同其實是算作兩個函式的(過載函式也是兩個不同的函式),因而如果基類是public virtual void a()而派生類是public void a(int a)其實是完全沒有問題的。對於new也是一樣。

base與this: 建構函式可以使用base關鍵字來強調構造過程中執行的父類建構函式以及引數(例如 public derivedclass() : base(3) {} ,假設基類有帶乙個int的構造方法...) 用於建構函式的this關鍵字可以指定執行本層級的被描述構造方法前執行某個另外的構造方法. (例如derivedclass有兩個構造方法,乙個是無引數的,另乙個是(int,int)構造的,這時無參的建構函式可以使用public derivedclass() : this (2,3) 呼叫derivedclass.derivedclass(2,3)構造. (在c++中不用this而是直接寫構造方法名字) . 當this用於類內部時類似於c++裡的this指標. this可以被當做引數傳遞給其他方法,相當於傳遞了物件自身的引用. this也可以用來指定類的成員(例如this.somedata,雖然與somedata效果一樣),可以明顯的區分區域性成員和類成員. 

類巢狀: class裡面可以定義class,這在c++中也很常見. 與c++類似的,c#中巢狀類中內層的類有訪問外層類私有成員或方法的許可權。如下

c++

class testclass

int getval()

class innerclass

};};

c#

public class testclass

}}

inte***ce與class: class可以通過繼承inte***ce來實現介面. 可以隱式實現或者顯式實現介面. 隱式實現即直接使用介面中的方法作為名稱, 例如介面imyinte***ce定義方法void method(). public class myclass : imyinte***ce 可以通過定義/重寫 void method()來實現介面. 基類實現某介面後,子類繼承時預設為以實現. 顯示實現即使用 "介面名稱.介面方法名稱" 進行實現. public class myclass2 : imyinte***ce 中定義/重寫為 void imyinte***ce.method() 。隱式實現的介面可以視為類的乙個屬性,跟隨類物件直接使用(myclass obj=new myclass(); obj.method(); ) 也可以使用介面物件訪問 ( myclass obj=new myclass(); imyinte***ce myinte***ceobj=obj; myinte***ceobj.method(); ) 但是顯式實現時就只能使用介面物件訪問了. ( myclass2 obj=new myclass2();imyinte***ce myinte***ceobj=obj; myinte***ceobj.method(); ) 

#region與#endregion : 這其實不應該算作語言內容,而應該算作ide擴充套件. 大致意思就是可以以#region ***開頭(***中內容隨意,一般為描述下面一大段**的功能),以#endregion結尾的一段**,可以被摺疊起來. (講道理c++的ifdef/endif等等也是可以被ide摺疊起來的) 不過如果**真的需要摺疊了,為什麼不考慮重構呢...

partial(部分類) 這是c#與c++比較不同的地方. c++類似的大概也就是.h中定義,.cpp中實現以及piml手法隱藏內部變數等等. c#這個partial據說是方便自動生成**與寫的**組合在一起. 使用partial的類在編譯時編譯器會將所有的內容拼接在一起形成乙個類. 如下: 

namespace csharptest1

}class program

}public partial class testclass /// part 2

}}/// end of namespace csharptest1

其實相當於dosomethingelse()和dosomething()寫在一起. 但是加上partial分開寫也沒有錯.

比較令我眼前一亮的是如果將part 2 這一部分的**去掉並不會產生編譯錯誤,而且執行的時候也不會產生異常。要知道類似的做法(即宣告乙個函式而不實現卻呼叫)在c/c++中會引起連線錯誤(link error)——一種最令人頭疼的錯誤(做跨平台的時候經常是編譯什麼的都過了,偏偏就是連線不上)。後來查了一下,這裡編譯器在編譯過程中未發現dosomethingelse()的實現於是就直接刪掉了dosomethingelse()的呼叫,並稱此舉能略微提高效能。看到這裡不得不說帶虛擬機器的語言就是比編譯型語言任性啊qwq

C 學習筆記(三)

c 運算子過載 1 過載運算子的運算順序和優先順序不變,但引數和返回型別是可以重新說明的。2 c 規定,運算子中,引數說明都是內部型別的,不能過載,如 int operator int,int 3 c 還規定了 這五個運算子不能過載,也不能創造新的運算子,如 4 c 規定 這四種運算子必須為成員形式...

C 學習筆記(三)

chapter 3 函式和類的自頂向下設計 1 乙個程式的開發過程 1.問題規範 2.分析 資料需求 3.設計 初始演算法 演算法精化 4.實現 5.測試 2 重要工具 結構圖 3 分析,設計程式時,甚至對任何問題來說,我們都要由大到小,層層分解,由乙個大問題分割成多個相關 的小問題,一口乙個蛋糕是...

C 學習筆記(三)

attributes field modifiers type variable declarators 域的修飾符field modifiers可以是 靜態域和非靜態域 下面的例子清晰的反映了二者之間的區別 域的初始化 如果在類中,沒有顯式的對域進行初始化,系統將賦予其乙個預設值。域的預設初始化分...