接續上篇C++基礎③new對象,繼承,友元函數,函數的可變參數
前言
在學Java的時候 , 我們會接觸到面向對象的三大特征,封裝,繼承,多態 。而Java是從C++里面脫胎出來的,所以也具有這些特征 , 在上篇中 , 介紹了繼承,友元函數等 , 今天來學習一下多態 。我相信大家對多態并不陌生 , C++中的多態和Java類似,只是實現起來有些差別 。說明一下:基礎篇只是對語言語法的簡單介紹, 并不會深入語言機制,將C++與Java的不同之處點出 , 所以相對比較枯燥 , 各位看官也可僅僅有個印象即可,再在用到的時候,就有跡可尋。
多態
C++的多態用法和Java類似 , 只是需要虛函數的支撐。
Meat.h
// 父類 .h
#pragma once
/*肉類*/
class Meat {
public:
// 使用虛函數 , 實現多態
virtual void getName();
};
Meat.cpp
#include "Meat.h"
#include <iostream>
using namespace std;
void Meat::getName() {
cout << "我是肉類 -- super class" << endl;
}
父類將要被復寫的函數需要virtual
表示 , 虛函數才具有之類復寫的特性。
Fish.h
#pragma once
/*
魚肉 繼承 肉類
*/
#include "Meat.h"
class Fish : public Meat {
public:
virtual void getName();
};
Fish.cpp
#include "Fish.h"
#include <iostream>
using namespace std;
void Fish::getName() {
cout << "我是魚肉。。。" << endl;
}
Chicken.h
#pragma once
/*
雞肉 繼承 肉類
*/
#include "Meat.h"
class Chicken : public Meat{
public:
virtual void getName();
};
Chicken.cpp
#include "Chicken.h"
#include <iostream>
using namespace std;
void Chicken::getName() {
cout << "我是雞肉。。。" << endl;
}
C++多態作用與用法和Java差不多
void printMeatInfo(Meat &m) {
m.getName();
}
/*使用多態*/
void usePolymorphism() {
Chicken c;
Fish f;
printMeatInfo(c);
printMeatInfo(f);
}
函數的對象參數使用引用傳遞,可以減少對象的的臨時生成,加大對內存空間的利用率。多態要在用的時候才會真正體會到他的便捷 , 在C++中配合純抽象類使用更佳 。
模板
C++中有模板函數還有模板類,類似于Java的泛型,在邏輯計算中,無需關心數據的具體類型 。在Java中,我們最常用的泛型救數List
, 例如:List<String> cities = new ArrayList();
下面,我們來看看C++的模板函數。
/*
模板函數 根據實際類型,自動推導
*/
template<typename T>
void anySwap(T &t1,T &t2) {
T tmp = NULL;
tmp = t1;
t1 = t2;
t2 = tmp;
}
/*使用模板函數*/
void useTemplateFunc() {
int i = 10;
int j = 30;
anySwap(i, j);
cout << "i = " << i << " j = " << j << endl;
cout << " ------- 字符交換 ---------" << endl;
char* c1 = "思念在蔓延";
char* c2 = "一通電話在世界兩邊";
anySwap(c1, c2);
cout << "c1 = " << c1 << " c2 = " << c2 << endl;
}
模板函數,在函數之前使用template<typename T>來聲明模板函數,T為自動推導類型。下面,我們用模板,來模擬一下Java的ArrayList類。
/*
CPP template class
模板類 , 相當于Java的泛型類 , 模擬Java集合類
*/
#include <iostream>
using namespace std;
/*
使用模板類加上純虛函數模擬Java的Collection接口
*/
template <typename T>
class Collection {
public:
virtual void add(T t) = 0;
virtual void del(T t) = 0;
virtual void change(int index, T t) = 0;
virtual T* query() = 0;
};
/*
模擬Java的ArrayList集合
*/
template <typename T>
class ArrayList : public Collection<T> {
public:
void add(T t) {
}
void del(T t) {
}
void change(int index, T t) {
}
T* query() {
return NULL;
}
};
class templateClassDemo {
public:
void useTemplateClass() {
// 在使用的時候指定模板類的類型
ArrayList<int> a;
a.add(1);
cout << "使用CPP模板類, 模擬Java集合類" << endl;
}
};
C++的模板特性和Java的泛型及其類似,只是寫法上有所區別,萬物都是相通的,變的是外在,不變的是算法核心。
異常
C++的異常比Java的異常處理自由,可以通過隨意的定義數字字符等拋出,然后通過catch函數參數類型去匹配。
/*CPP 可以拋出任意類型的Exception*/
void throwStringException() {
throw "拋出字符類型Exception";
}
void throwIntException() {
throw 1;
}
/*捕獲異常*/
void catchException() {
try
{
throwStringException();
throwIntException();
}
catch (char* e)
{
cout <<"捕獲String類型的異常信息 : "<< e << endl;
}
catch (int e1) {
cout << "捕獲int類型的異常信息:" << e1 << endl;
}
}
自定義異常
/*自定義異常類*/
class CustomException {
public:
CustomException(char* msg) {
this->msg = msg;
}
char* showMsg() {
return this->msg;
}
private:
char* msg;
};
使用
// use
void throwObjectException() {
// 不要拋異常指針 , new了對象指針之后必須銷毀 , 并且還會產生對象副本,占內存
// 還有標準異常處理 , 查看API
throw CustomException("我是自定義對象異常");
}
/*捕獲異常*/
void catchException() {
try
{
throwObjectException();
}
catch (CustomException &ex) {
cout << "捕獲自定義異常:" << ex.showMsg() << endl;
}
}
結語
C++基礎系列基本上到此結束了,因其基本語法與C比較像,就沒做過多介紹,基本上只做了面向對象部分的介紹。
C++基礎系列,斷斷續續,今天總算是可以告一段落了 , 上個月由于一些事情停更了一段時間,日子也沒以前那么悠閑了 , 要學的東西如排山倒海般涌來,IT行業的發展是越來越快,要學的也越來越多,大到各種語言學習C/C++ , Java , Python , JavaScript 。小到各種奇淫巧技 , 無所不包 。
語言不是限定 , 沒有哪一個項目只用一種語言可以搞定的,學習語言,不只是學習那門語言的語法,更重要的是那門語言思想 。
后續系列文章計劃
一 , 開始撰寫Android UI系列
二 , 開始不定期撰寫JavaScript系列(基礎)
因其工作及自身原因,NDK實戰項目現在并沒有很多時間撰寫,初步計劃在元月初在家的時候開始逐步更新NDK實戰項目。