1. 程式人生 > >【2016/3】C++ 類與物件進階 運算子過載 new delete 模板 繼承

【2016/3】C++ 類與物件進階 運算子過載 new delete 模板 繼承

類與物件:

const常量哪怕棧空間資料被改 被訪問時依然是使用存於符號表的資料

建構函式的形式:
拷貝構造 Test(Test &t){}
初始化構造 Test(int d): data(d){}

   Test t(10);
   t = 200;    
   //只要型別不同,會建立一箇中間的無名變數來賦值;
   //實際上是呼叫了建構函式中的 Test(200) 建立了一個物件,將物件賦值給t;
   //如果建構函式中使用explicit作為修飾,不能隱式轉化時,會杜絕這種情況發生;
   //上一行的情況則必須 使用:   t = (Test) 200;

   Test t1 = t2;       //拷貝構造
Test t1; t1 = t2; //運算子過載賦值

拷貝構造: 形如 void fun(Test a);
如果函式的引數是以傳入物件的形式, 那麼傳入物件的時候會進行一次拷貝構造

     返回值是物件的時候: Test fun(int a)
                         {
                             Test new_one(a);
                             return new_one;
                         }
如果編譯器做了優化 可能會延長返回物件的生存週期 而不是重新拷貝構造一個無名物件來返回

*拷貝構造的時候要考慮淺拷貝和深拷貝的問題

         注意: 區域性物件不能以引用形式返回,區域性物件會被銷燬

*拷貝構造的引數最好使用const修飾 比如Test(const Test &t)(…)
因為return的時候可能會檢測到拷貝建構函式,而return返回的物件具有常性,需要const屬性

賦值函式的編寫:
1.自身賦值問題
2.釋放原有記憶體的空間
3.開闢空間深拷貝賦值資料
4.返回自身物件
—- Tip:異常安全問題 在賦值期間發生異常 保證賦值兩者的資料安全

*類成員有指標的時候 考慮拷貝構造和析構還有運算子過載的安全性

vld.h: 檢測記憶體洩露的庫

Question: C++的類的初始的函式有六個 分別是什麼?
explicit關鍵字的用法?
如何把一個只有一個數據成員的物件直接給一個該資料的變數賦值?(Test t(200); int value = t;)

成員函式中用const修飾的方法:
void Test::fun()const;
實際上相當於
void Test::fun(const Test * const this);
本質上就是不能修改this所指的物件的值;
***tips: 常方法不能呼叫有可能改變物件的值的成員函式;

成員函式中的static修飾的方法:
static修飾的變數以及函式,被所有物件共享,沒有this指標;
***tips: 靜態方法不能呼叫成員函式,因為它是被所有類物件共享的;

用friend關鍵字修飾的友元函式可以訪問私有成員;
— 常用來過載流運算子;

運算子過載:

   **不能使用的過載運算子:**
       三目運算子: ?:
       成員訪問符: . .*
       字長訪問符: sizeof
       作用域符:   ::
++運算子的過載:
    前置++: Test operator++();
    後置++: Test operator++(int);
        此處的int僅作為標記使用;
流運算子過載:
   friend ostream& operator<<(ostream &out, const Test &t);
   {
       out << t.data;
       return out;
   }

作為友元函式進行過載;

C++如何實現的過載:
   編譯器在彙編階段根據函式的引數通過自己的一套命名方式
   將函式進行一系列重新命名,翻譯成另一個具有唯一性的名字(帶上函式的引數)

   當加入extern "C" 修飾函式的時候用C的模式彙編

空間分配(new && delete):

new 等同於 C 語言中的 (強制轉化 *)malloc(sizeof(型別));

   int *p   = new int(10);     //新建一個值為10的整形
   int *p   = new int[10];     //新建一個有10個成員的整形陣列

   int *p   = new Test;        //呼叫建構函式申請空間(如果要求有引數必須寫引數)

   int *p   = new Test[10];    //構造10個物件!
                               //Tips: 如果要直接構造,一定要有預設(帶參)的建構函式
   delete []p;                 //*** 通過delete刪除掉連續申請的物件空間 否則記憶體洩露
       //方括號只起到標記作用,標識是釋放一個數組空間

new的步驟:
1.申請空間;
2.呼叫建構函式在申請的空間內構造物件;

delete的步驟:
1.呼叫解構函式析構物件;
2.釋放空間;

模板:

   #include <typeinfo>
   template<typename Type>
   Max(Type a, Type b)
   {
       cout<<typeid(Type).name()<<endl;
       //打印出Type的型別
       return a>b ? a:b;
   }

實現是先通過一系列操作與函式模板, 製作出相應型別的模板函式
最後再用模板函式來實現函式功能

類的形式類似;

可以直接呼叫:
Max(1,2);
Max(‘A’, ‘X’);
或者顯式呼叫:
Max(1,2);
Max(‘A’, ‘X’);

Gdb除錯:

1.g++ -o -g
2.gdb
3.list
4.b 加斷點
5.run

new && delete:

1.new operator -> 1)分配空間 2)建構函式
              (直接使用 new 關鍵字)
2.operator new -> 只分配空間
              (直接使用 operator new 關鍵字)

可以過載new操作符來影響其分配空間的操作

   void *operator new(size_t sz)
   {
       void *p = malloc(sz);
       return p;
   }

要求返回值void * 傳入引數 size_t

同時如果你過載了new操作符,就要求你過載delete操作符

   void operator delete(void *p)
   {
       free(p);
   }

*Tips:free 與 malloc對應
new 與 delete對應
operator new 與 operator delete 對應

同理 new[] 與 delete[] 也可以過載
實際上new[] 在申請空間的時候,
頭部會多出一部分cookie空間, 大小為一個指標的大小
儲存著使用者的資訊:起始位置,釋放多少個物件
此時才可以以delete[]來釋放相應的空間

類裡面也可以過載new delete操作符,而且會被物件優先使用

如果是void*p = new Test(10);
那麼delete p的時候 不會呼叫類的解構函式;

3.placement new

通過malloc開闢空間之後
int p = (int )malloc(sizeof(int) * 10)
可以通過new(p)int(10)來對申請的空間進行賦值
這種語法稱之為定位new

這樣的new也是可以過載的:

   void *operator new(size_t sz, void *data, int pos)
   {
       return (data + pos);
   }

則使用方法變為

new(p, 3)int(200);

對p所指的第三個位置進行賦值200的操作

繼承和多型:

子類雖然公有繼承了基類的私有成員
但是依然不能在自己的方法中改變基類
正確的用法是在基類中設定相應的設定方法來設定基類的成員

父類的資訊能否被子類調動?
   ***父類任意私有資料都不能被子類直接呼叫
   但是父類的公有方法與保護方法都可以被子類的方法呼叫
   只有公有方法可以被物件直接訪問
保護方法存在的意義:
   ***保護只在繼承的時候體現它的性質
   不想被外部的物件呼叫, 為了給子類提供藉口而存在
   其他一切特點等同於私有

class C: D
預設是私有繼承 (class C: private D)

多繼承:
   多繼承的建構函式順序就是繼承列表從左往右
   同時先構造成員的類物件再構造自身類物件
   建構函式書寫方法:
   C(a, b, c): A(a), B(b), C(c){}
   子類要呼叫基類的構造方法

   二義性:
       父類有同名的變數
       那麼需要通過加入 父類:: 來避免二義性
虛繼承:
   可以避免繼承同一個基類產生變數的二義性
同名隱藏:
   如果子類和父類有同名的方法
   那麼父類的同名方法會完全被隱藏(哪怕是過載)
   但是可以通過使用::這個來直接呼叫父類方法

看書:
1.過載 2.覆蓋 3.隱藏

相關推薦

2016/3C++ 物件 運算子過載 new delete 模板 繼承

類與物件: const常量哪怕棧空間資料被改 被訪問時依然是使用存於符號表的資料 建構函式的形式: 拷貝構造 Test(Test &t){} 初始化構造 Test(int d): data(d){} Test

C/C++學院0831-物件的異常/面試100題1-100

類與物件的異常 Cpp異常 #include <iostream> #include <string.h> using namespace std; //標識錯誤的型別

C++C++物件的概念

C++中的類也是一種構造型別,但是進行了一些擴充套件,類的成員不但可以是變數,還可以是函式;通過類定義出來的變數也有特定的稱呼,叫做“物件”。 通過結構體定義出來的變數還是叫變數,而通過類定義出來的變數有了新的名稱,叫做物件(Object)。 有些資料也將類的成員

小朋友學C++(3):物件

(一)類與物件 類是由我們根據客觀事物抽象而成,形成一類事物,然後用類去定義物件,形成這類事物的具體個體。 比如小狗是一個類,你家的“旺財”則是小狗一個具體的物件。 (二)屬性與方法 一般把類的資料成員稱為類的屬性,把類的函式成員稱為方法。 比如小

c++物件之預設成員函式

c++類與物件(二) 1.類的6個預設成員函式 一:建構函式 建構函式是一個特殊的成員函式,名字與類名相同,建立類型別物件時由編譯器自動呼叫,保證每個資料成員都有一個合適的初始值,並且在物件的生命週期內只調用一次。 建構函式是特殊的成員函式,其特徵如下:

C++:物件

類中的預設成員函式 類中預設成員函式一共有六個:(1)建構函式(2)拷貝建構函式(3)解構函式(4)賦值操作符過載(5)取地址操作符過載(6)const修飾的取地址操作符修改。 一.建構函式 建構函式就是隨著物件被建立而自動呼叫的公有成員函式,有且僅在物件被定義時,自動呼叫一次,主要用於

C++物件基本語法(1)

一、概述 1、什麼是物件 1、萬物皆物件。 2、程式就是一組物件,物件之間通過訊息交換資訊。 3、類就是對物件的描述和抽象,物件就是類的具體化和例項化。 2、通過類描述物件 類就是從屬性和行為兩個方面對

C++物件

C++是一門基於物件的語言,不是完全面向物件的語言(Java時一門純面向物件的語言)。那麼什麼事面向物件呢?面向物件就是我們關注的時物件,我們把一件事情分成幾部分來協同完成一件事,每一部分我們稱為物件。C語言是一門面向過程的一門語言,面向過程就是我們把一件事情按步驟完成,每一

c#物件(this)

元件程式設計不是對傳統面向物件的拋棄,相反元件程式設計正是面向物件程式設計的深化和發展。類作為面向物件的靈魂在C#語言裡有著相當廣泛深入的應用,很多非常“Sharp”的元件特性甚至都是直接由類包裝而成。對類的深度掌握自然是我們“Sharp XP”重要的一環。 類 C#的類是

C++物件初學

一.基本內容總結(一)基礎知識1.類的定義:類是對具有相同屬性和行為的一組物件的抽象和統一描述。是使用者自定義的資料型別。/類的定義包括行為和屬性兩部分。/屬性以資料表示,行為通過函式實現。C++類定義的說明語句一般形式為:class<類名> { public

C++物件詳解

一、什麼是類 1-1 程式設計的發展   我們知道程式的發展經過了大概三個階段:面向機器的程式設計、面向過程(結構)程式設計、面向物件程式設計。其中面向機器的程式設計主要採用二進位制指令或者組合語言進行程式的編寫。這種方式對計算機來說是很容易理解的,

C++ 物件

  在上篇的最後的例項程式程式碼中,我所寫的成員函式中的引數變數名和資料成員名一樣,為了編譯時不發生錯誤,我在資料成員的前面加上"類名::"以區分。其實還有另外一種方法可以來加以區分,那就是C++中的自引用指標this。今天就講一下C++中的this以及string類。可能程式碼不會很多,但突出原理;

讀書筆記C陷阱缺陷

詞法陷阱 = 不同於 == &和|不同於&&和|| 詞法分析的“貪心法”:從左到右一個字元一個字元地讀入,如果該字元能組成一個符號,那麼再讀入下一個字元,判斷這兩個字元組成的字串是否可能是一個符號的組成部分。(需要注意的是,除了字串和字元常量,符號間

學習筆記c++ 過載運算子

最近學校C++學到了類,要求自己實現一個向量類,做了一部分典型的過載運算子,以作筆記。 本類Vector對應的是一個向量,通過一個長度為n的陣列(為了簡化而取int)對應n維向量。 class Vector{//首先是類申明,用的建構函式是預設建構函式,

備忘2018年 java入門主流框架學習到架構電商專案實戰

0001-多執行緒快速入門.zip 0002-多執行緒執行緒安全.zip 0003-多執行緒之間通訊.zip 0004-java併發包與併發佇列.zip 0005-執行緒池原理剖析與鎖的深度化.zip 0006-資料交換格式與反射機制與SpringIOC原理分析.zip 00

函數02、函數

作用域一、函數的返回值In [4]: def add(x, y): ...: return x+y ...: In [5]: add(1, 2) Out[5]: 3 In [8]: def add(x, y): ...: return x+y ...:

C#——物件

一、類和物件的區別 類:類是模型,確定物件將會擁有的特徵(屬性)和行為(方法),類是物件的型別。 類是抽象的概念,僅僅是模板,比如說“人”類 物件是一個能看得到、摸得到的具體實體 物件可以叫做類的例項(Instance) 類不佔記憶體,物件才佔記憶體 二、類的定

C/C++學院0831-對象的異常/面試100題1-100

oid tdi 面試 mod get() ng- java article ron 類與對象的異常 Cpp異常 #include <iostream> #include <string.h> using namespace st

C++初學物件的概念

C++中的類Class可以看作C語言中結構體的升級版。結構體是一種構造型別,它可以包含若干成員變數,而其中每個成員變數的型別又可以不同。例如: struct Student {//結構體包含的成員變數 char *name; int age; float score; }; void D

C++C++的定義和物件的建立

類是建立物件的模板,一個類可以建立多個物件,每個物件都是類型別的一個變數;建立物件的過程也叫類的例項化。每個物件都是類的一個具體例項(Instance),擁有類的成員變數和成員函式。 在面向物件的程式語言中,經常把函式(Function)稱為方法(Method)。