C++之面向?qū)ο蟮恼Z法筆記

前言

最近項(xiàng)目在開發(fā)涉及到的C++內(nèi)容相對比較多凉倚,整理一下卦睹,過程中用到的C++面向?qū)ο蟮恼Z法筆記

正文

知識點(diǎn)的概要

  • C++ 類 & 對象
  • 值傳遞&引用傳遞
  • 拷貝構(gòu)造函數(shù)
  • 繼承& 多態(tài)
  • 友元
  • 模板
  • 類型轉(zhuǎn)換
  • 異常捕獲

類& 對象

  • C++類定義:本質(zhì)上是定義一個數(shù)據(jù)類型的合集
    類定義是以關(guān)鍵字 class 開頭疗我,后跟類的名稱袖迎。類的主體是包含在一對花括號;
class Teacher
{
public:
    Teacher(); //構(gòu)造函數(shù) (malloc)
    Teacher(int age, char * name); //構(gòu)造函數(shù) (malloc)
    ~Teacher();  //析構(gòu)函數(shù) 釋放在構(gòu)造函數(shù)里面動態(tài)申請的內(nèi)存 (free)

    void setAge(int age);
    int getAge();
    void setName(char *name);
    char* getName();

private:
    int age;
    char *name;
};
  • C++對象的定義
    聲明類的對象鸽心,就像聲明基本類型的變量一樣
Teacher teacher1;  //無參構(gòu)造函數(shù)聊闯,也可以Teacher teacher1 = Teacher();
Teacher teacher2(28, "kevin");  //有參構(gòu)造函數(shù)布疼,創(chuàng)建對象, 也可以Teacher teacher2 = Teacher(28, "kevin");
Teacher *p_teacher = new Teacher(29,"chenyu");  //對象指針摊趾,創(chuàng)建可直接new關(guān)鍵字或者下面的方式
Teacher *p_teacher2;
p_teacher2 = &teacher1;
  • 完整的例子
    Teacher.h:
#pragma once
class Teacher
{
public:
    Teacher(); //構(gòu)造函數(shù) (malloc)
    Teacher(int age, char * name); //構(gòu)造函數(shù) (malloc)
    ~Teacher();  //析構(gòu)函數(shù) 釋放在構(gòu)造函數(shù)里面動態(tài)申請的內(nèi)存 (free)

    void setAge(int age);
    int getAge();
    void setName(char *name);
    char* getName();
private:

    int age;
    char *name;

};

Teacher.cpp:

#include "Teacher.h"
#include <iostream>

//c++ 標(biāo)準(zhǔn)庫的命名空間
using namespace std;

Teacher::Teacher()
{
    cout << " Teacher 構(gòu)造函數(shù)  地址:" << this << endl;
}

Teacher::Teacher(int age, char * name) 
{
    cout << " Teacher 構(gòu)造函數(shù)  地址:" << this << endl;
    this->age = age;
    this->name = name;
    cout << " Teacher age :" << age << " name :"<< name << endl;
}


Teacher::~Teacher()
{
    cout << " Teacher 析構(gòu)函數(shù)  地址:" << this << endl;
}


void Teacher::setAge(int age) {
    cout << "Teacher setAge is " << age << endl;
    this->age = age;
}
int Teacher::getAge() {
    return this->age;
}
void Teacher::setName(char *name) {
    cout << " Teacher setName is " << name << endl;
    this->name = name;
}
char* Teacher::getName() {
    return this->name;
}

main.cpp:

#include "Teacher.h"
#include "Student.h"
#include <iostream>

using namespace std;

void fun() {
    Teacher teacher1;  //無參構(gòu)造函數(shù)币狠,也可以Teacher teacher1 = Teacher();
    Teacher teacher2(28, "kevin");  //有參構(gòu)造函數(shù),創(chuàng)建對象, 也可以Teacher teacher2 = Teacher(28, "kevin");
    Teacher *p_teacher = new Teacher(29,"chenyu");  //對象指針砾层,創(chuàng)建是需要new關(guān)鍵字

    teacher1.setAge(31);
    teacher1.setName("jason");

    cout << "teacher1 name: " << teacher1.getName() << endl;
    cout << "teacher1 age: " << teacher1.getAge() << endl;

    cout << "teacher2 name: " << teacher2.getName() << endl;
    cout << "teacher2 age: " << teacher2.getAge() << endl;

    cout << "p_teacher name: " << p_teacher->getName() << endl;
    cout << "p_teacher age: " << p_teacher->getAge() << endl;

    //及時釋放
    delete p_teacher;
    p_teacher = nullptr;

}

void main() {
    fun();
    system("pause");
}

值傳遞&引用傳遞

在函數(shù)調(diào)用中漩绵,如果需要將類的對象作為形參,傳入到某個函數(shù)進(jìn)行調(diào)用肛炮,這種情況分為值傳遞和引用傳遞止吐。

  • 值傳遞
//為什么這里只調(diào)用了析構(gòu)函數(shù),沒有調(diào)用構(gòu)造函數(shù)铸董?
//值傳遞 存在值拷貝
void funValuePass(Teacher teacher) 
{
    teacher.setAge(31);
    teacher.setName("liuyan"); 

    cout << "funValuePass teacher name: " << teacher.getName() << endl;
    cout << "funValuePass teacher age: " << teacher.getAge() << endl;
}
  • 引用傳遞
    什么是引用祟印?

引用是原變量的一個別名.
n 相當(dāng)于m 的別名(綽號),對n 的任何操作就是對m 的操作粟害。例如有個人叫是JackMa蕴忆,綽號是“馬爸爸”。說“馬爸爸”怎么怎么的悲幅,其實(shí)就是在說JackMa套鹅。所以n 既不是m 的拷貝,也不是指向m 的指針汰具,其實(shí)n就是m 它自己卓鹿。
c++中的引用 (就是再堆中分配空間)

堆空間內(nèi)存分配.jpg

堆(heap)空間:
動態(tài)分配的內(nèi)存(malloc 等api 分配在堆空間, c++中的new)
堆用于存放進(jìn)程運(yùn)行時動態(tài)分配的內(nèi)存段,可動態(tài)擴(kuò)張或縮減留荔。堆中內(nèi)容是匿名的吟孙,不能按名字直接訪問,只能通過指針間接訪問聚蝶。
棧(stack)空間:
局部變量杰妓、函數(shù)參數(shù)、返回地址等(系統(tǒng)自動分配的臨時內(nèi)存)Linux有專門的寄存器管理?xiàng)?nèi)存(效率高)
.bss段
未初始化或初值為0的全局變量和靜態(tài)局部變量
.data段
已初始化且初值非0的全局變量和靜態(tài)局部變量
.text段
可執(zhí)行代碼碘勉、只讀變量,全局靜態(tài)變量

//引用傳遞
//c++ 引用 是內(nèi)存空間的別名 不存在拷貝 只傳遞內(nèi)存別名
void funRefPass(Teacher &teacher) {

    teacher.setAge(32);
    teacher.setName("Chen"); 

    cout << "funRefPass teacher name: " << teacher.getName() << endl;
    cout << "funRefPass teacher age: " << teacher.getAge() << endl;
}
  • 引用和指針的區(qū)別
  1. 指針是一個實(shí)體巷挥,而引用僅是個別名;
  2. 引用使用時無需解引用(*)验靡,指針需要解引用倍宾;
  3. 引用只能在定義時被初始化一次,之后不可變胜嗓;指針可變高职; 引用“從一而終” 。
  4. 引用沒有 const辞州,指針有 const怔锌,const 的指針不可變;
  5. 引用不能為空,指針可以為空产禾;
  6. “sizeof 引用”得到的是所指向的變量(對象)的大小,而“sizeof 指針”得到的是指針本身(所指向的變量或?qū)ο蟮牡刂罚┑拇笮牵啦。?/li>
  7. 引用是面向?qū)ο蟮母拍钛乔椋羔樖敲嫦蜻^程種的概念,C++能夠混編C語言哈雏,所以C++支持指針
  • 代碼調(diào)用
    值引用:
void main() {

    Teacher teacher;

    teacher.setAge(24);
    teacher.setName("lily");
        //值傳遞
    funValuePass(teacher);
        //這邊值沒有發(fā)生變化
    cout << "teacher name: " << teacher.getName() << endl;
    cout << "teacher age: " << teacher.getAge() << endl; 
    system("pause");
}

輸出結(jié)果:


值傳遞的結(jié)果.png

引用傳遞:

void main() {

    Teacher teacher;

    teacher.setAge(24);
    teacher.setName("lily");
        //引用傳遞
    funRefPass(teacher);
       //這邊值已經(jīng)發(fā)生變化
    cout << "teacher name: " << teacher.getName() << endl;
    cout << "teacher age: " << teacher.getAge() << endl; */
    system("pause");
}

輸出結(jié)果:


引用傳遞的結(jié)果.png

拷貝構(gòu)造函數(shù)

拷貝構(gòu)造函數(shù)是一種特殊的構(gòu)造函數(shù)楞件,它在創(chuàng)建對象時,是使用同一類中之前創(chuàng)建的對象來初始化新創(chuàng)建的對象裳瘪。
拷貝構(gòu)造函數(shù)通常用于:

  1. 通過使用另一個同類型的對象來初始化新創(chuàng)建的對象土浸。
  2. 復(fù)制對象把它作為參數(shù)傳遞給函數(shù)。
  3. 復(fù)制對象彭羹,并從函數(shù)返回這個對象黄伊。
    對拷貝,C++ 的String源碼派殷,最能體現(xiàn)还最。
    舉個例子區(qū)分賦值和拷貝
String  s1("aaa");
String  s2("bbb");
String  str = s1; //這個就是調(diào)用了拷貝構(gòu)造函數(shù),等同String str(s1);
             str  = s2 //這個是調(diào)用賦值函數(shù)

拷貝分為 淺拷貝深拷貝
淺拷貝:位拷貝毡惜,拷貝構(gòu)造函數(shù)拓轻,賦值重載,多個對象共用同一塊資源经伙,同一塊資源釋放多次扶叉,崩潰或者內(nèi)存泄漏
深拷貝:每個對象共同擁有自己的資源,必須顯式提供拷貝構(gòu)造函數(shù)和賦值運(yùn)算符

  • 淺拷貝
Student::Student(const Student &student) {
  cout << " MyStudent 拷貝構(gòu)造函數(shù)  地址:" << this << endl;
  this->age = student.age;
  this->name = student.name;
  this->teacherName = student.teacherName;
}
  • 深拷貝
Student::Student(const Student &student) {
    cout << " Student 深拷貝構(gòu)造函數(shù)  地址:" << this << endl;
    int len = strlen(student.name);
    this->name = (char *)malloc(len + 1);
    strcpy(this->name, student.name);

    len = strlen(student.teacherName);
    this->teacherName = (char *)malloc(len + 1);

    strcpy(this->teacherName, student.teacherName);
}
  • 完整的例子
    Student.h:
#pragma once
class Student
{
public:
    Student(int age, char *name, char *teacherName);
    ~Student();

/*private:
    //重寫默認(rèn)的拷貝構(gòu)造函數(shù) 這種方案不常用
    MyStudent(const MyStudent &student);*/
    Student::Student(const Student &student);
public:
    int age;
    char *name;
    char *teacherName;

};

Student.cpp:

#include "Student.h"
#include <iostream>

using namespace std;

Student::Student(int age, char *name, char *teacherName)
{
    cout << " Student 構(gòu)造函數(shù)  地址:" << this << endl;
    int len = strlen(name);
    this->name = (char *)malloc(len + 1);
    strcpy(this->name, name);

    len = strlen(teacherName);
    this->teacherName = (char *)malloc(len + 1);

    strcpy(this->teacherName, teacherName);
}


Student::~Student()
{
    cout << " Student 析構(gòu)函數(shù) 地址:" << this << endl;
    free(this->name); //拷貝構(gòu)造函數(shù)釋放野指針出錯
    free(this->teacherName);
}


//默認(rèn)拷貝構(gòu)造函數(shù) 實(shí)現(xiàn)淺拷貝
/*Student::Student(const Student &student) {

cout << " MyStudent 拷貝構(gòu)造函數(shù)  地址:" << this << endl;
this->age = student.age;
this->name = student.name;
this->teacherName = student.teacherName;

}*/

//覆蓋默認(rèn)的拷貝構(gòu)造函數(shù) 實(shí)現(xiàn)深拷貝
Student::Student(const Student &student) {

    cout << " Student 深拷貝構(gòu)造函數(shù)  地址:" << this << endl;
    int len = strlen(student.name);
    this->name = (char *)malloc(len + 1);
    strcpy(this->name, student.name);

    len = strlen(student.teacherName);
    this->teacherName = (char *)malloc(len + 1);

    strcpy(this->teacherName, student.teacherName);

}

main.cpp:

// 1. 淺拷貝
// 2.避免淺拷貝引發(fā)野指針問題
//   2.1 深拷貝
//  2.2 私有化拷貝構(gòu)造函數(shù) 
void copyTest() {
    Student student = Student(21, "Jake", "Jhone");
    cout << "setFunX student1 name: " << student.name << endl;
    cout << "setFunX student1 age: " << student.age << endl;
    cout << "setFunX student1 age: " << student.teacherName << endl;
    Student st2 = student;  // 這里也調(diào)用了拷貝構(gòu)造函數(shù)
    cout << "setFunX student2 name: " << st2.name << endl;
    cout << "setFunX student2 age: " << st2.age << endl;
    cout << "setFunX student2 age: " << st2.teacherName << endl;
}

void main() {
    copyTest();
    system("pause");
}

繼承& 多態(tài)

繼承

當(dāng)創(chuàng)建一個類時帕膜,您不需要重新編寫新的數(shù)據(jù)成員和成員函數(shù)枣氧,只需指定新建的類繼承了一個已有的類的成員即可。這個已有的類稱為基類泳叠,新建的類稱為派生類作瞄。
C++ 繼承的繼承指的就是基類和派生類的關(guān)系。

  • 代碼:

基類Plane.h

#pragma once
#include <string>

using namespace std;

class Plane
{
public:
    Plane();
    Plane(std::string name, int year);
    ~Plane();

    void fly();
    void land();
    void printf();
protected:
    std::string name;
    int year;
};

基類Plane.cpp

#include "Plane.h"
#include <iostream>

using namespace std;

Plane::Plane() :name("灣流"), year(1991) {
    cout << "Plane  無參構(gòu)造函數(shù)" << name << year << endl;
}

Plane::Plane(std::string name, int year) :name(name), year(year) {
    cout << "Plane 構(gòu)造函數(shù)" << name << year << endl;
}

Plane::~Plane()
{
    cout << "Plane 析構(gòu)函數(shù)" << endl;
}

void Plane::fly() {
    cout << "Plane fly" << endl;
}

void Plane::land() {
    cout << "Plane land" << endl;
}

void Plane::printf() {
    cout << "Plane printf " << "name = " << name << " year = " << year << endl;
}

派生類Jet.h:

#include "Plane.h"

class Jet : public Plane
{
public:
    Jet();
    Jet(std::string name, int year);
    ~Jet();

    void fly();

    void land();
    void test();
};

派生類Jet.cpp:

#include "Jet.h"
#include <iostream>

using namespace std;

Jet::Jet() {
    cout << "Jet  無參構(gòu)造函數(shù)" << name << year << endl;
}

Jet::Jet(std::string name, int year) {
    cout << "Jet  構(gòu)造函數(shù)" << name << year << endl;
}


Jet::~Jet() {
    cout << "Jet 析構(gòu)函數(shù)" << endl;
}

//重寫
void Jet::fly() {
    cout << "Jet fly" << endl;
}

void Jet::land() {
    cout << "Jet land" << endl;
}

void Jet::test() {
}

調(diào)用類main.cpp:


//1. 先調(diào)用父類的構(gòu)造函數(shù)
//2.釋放時先調(diào)用子類的析構(gòu)函數(shù)

//子類沒有 就使用父類的方法
//子類有實(shí)現(xiàn)危纫,就是用子類的重寫
//父類型的引用 賦值子類型的對象 方法都是父類型中的方法
void funExtends() {
    Jet jet;
    //jet.fly();

    //jet.Plane::fly();
    Plane *pl = &jet;
    pl->fly();

    Plane &p2 = jet;
    p2.fly();
}

void main() {
    funExtends();
    system("pause");
}

輸出結(jié)果:父類型的引用 賦值子類型的對象 方法都是父類型中的方法


輸出結(jié)果.png

輸出的結(jié)果宗挥,調(diào)用的還是父類的方法,不是子類的方法种蝶,上面的情況明顯不是我們想要的結(jié)果契耿,怎么解決呢?
方法:使用虛函數(shù) 讓派生類類 重載父類方法
在Plane.h中螃征,將fly和land兩個方法添加virtual進(jìn)行修飾

    virtual void fly();
    virtual void land();

再次輸出結(jié)果:


期望的結(jié)果.png
  • 繼承類型
    如下代碼:A繼承基類B的時候搪桂,帶著修飾符,繼承的修飾符有三種:public、protected踢械、private酗电。
class A : public B{};

我們幾乎不使用 protected 或 private 繼承,通常使用 public 繼承内列。當(dāng)使用不同類型的繼承時撵术,遵循以下幾個規(guī)則:

繼承類型 說明
public 當(dāng)一個類派生自公有基類時,基類的公有成員也是派生類的公有成員话瞧,基類的保護(hù)成員也是派生類的保護(hù)成員嫩与,基類的私有成員不能直接被派生類訪問,但是可以通過調(diào)用基類的公有和保護(hù)成員來訪問交排。
protected 當(dāng)一個類派生自保護(hù)基類時划滋,基類的公有和保護(hù)成員將成為派生類的保護(hù)成員。
private 當(dāng)一個類派生自私有基類時埃篓,基類的公有和保護(hù)成員將成為派生類的私有成員处坪。
  • 多繼承
    多繼承即一個子類可以有多個父類,它繼承了多個父類的特性架专。類似一個人可以有多個師傅稻薇;
class A{};
class B{};
class C: public A, public B{}胶征;

多態(tài)

  • 概念
    多態(tài)按字面的意思就是多種形態(tài)塞椎。當(dāng)類之間存在層次結(jié)構(gòu),并且類之間是通過繼承關(guān)聯(lián)時睛低,就會用到多案狠。C++ 多態(tài)意味著調(diào)用成員函數(shù)時,會根據(jù)調(diào)用函數(shù)的對象的類型來執(zhí)行不同的函數(shù)钱雷。
    C++的多態(tài)性用一句話概括就是:在基類的函數(shù)前加上virtual關(guān)鍵字骂铁,在派生類中重寫該函數(shù),運(yùn)行時將會根據(jù)對象的實(shí)際類型來調(diào)用相應(yīng)的函數(shù)罩抗。如果對象類型是派生類拉庵,就調(diào)用派生類的函數(shù);如果對象類型是基類套蒂,就調(diào)用基類的函數(shù)钞支。
  • 實(shí)例解釋
    以上面的plane類為例,jet繼承了Plane操刀,是plane的派生類烁挟,在進(jìn)行創(chuàng)建一個Copter派生類 繼承Plane基類
    Copter.h:
#include "Plane.h"

class Copter : public Plane
{
public:
    Copter();
    Copter(std::string name, int year);
    ~Copter();

    void fly();

    void land();

};

Copter.cpp:

#include "Copter.h"
#include <iostream>

using namespace std;

Copter::Copter() {
    cout << "Copter  無參構(gòu)造函數(shù)" << name << year << endl;
}

Copter::Copter(std::string name, int year) {
    cout << "Copter  構(gòu)造函數(shù)" << name << year << endl;
}

Copter::~Copter() {
    cout << "Copter 析構(gòu)函數(shù)" << endl;
}

//重寫
void Copter::fly() {
    cout << "Copter fly" << endl;
}

void Copter::land() {
    cout << "Copter land" << endl;
}

調(diào)用

    Plane *plane;
    Jet jet("波音707", 1997);
    Copter copter("絕影", 2005);

    // 存儲Jet的地址
    plane = &jet;
    // 調(diào)用Jet的函數(shù) fly
    plane->fly();

    // 存儲copter的地址
    plane = &copter;
    // 調(diào)用Copter的函數(shù) fly
    plane->fly();

編譯輸出結(jié)果:


image.png
  • 分類
    虛函數(shù) (c++多態(tài)的基礎(chǔ)) 增加程序的擴(kuò)展性
    動態(tài)多態(tài): 程序運(yùn)行過程中,覺得哪一個函數(shù)被調(diào)用
    靜態(tài)多態(tài): 重載(函數(shù)名稱相同骨坑,參數(shù)不同撼嗓,面向?qū)ο蟮奶匦В琧 中不行)

  • 發(fā)生動態(tài)多態(tài)的條件:

  1. 繼承
  2. 父類的引用或者指針指向子類的對象
  3. 函數(shù)的重寫

重載(overload):在相同作用域內(nèi),函數(shù)名稱相同且警,參數(shù)或常量性(const)不同的相關(guān)函數(shù)稱為重載粉捻。重載函數(shù)之間的區(qū)分主要在參數(shù)和常量性(const)的不同上,若僅僅是返回值或修飾符 virtual斑芜,public/protected/private的不同不被視為重載函數(shù)(無法通過編譯)杀迹。不同參數(shù)是指參數(shù)的個數(shù)或類型不同,而類型不同是指各類型之間不能進(jìn)行隱身類型轉(zhuǎn)換或不多于一次的用戶自定義類型轉(zhuǎn)換(關(guān)于類型轉(zhuǎn)換押搪,請參考前文:類型轉(zhuǎn)型(Type Casting))。當(dāng)調(diào)用發(fā)生時浅碾,編譯器在進(jìn)行重載決議時根據(jù)調(diào)用所提供的參數(shù)來選擇最佳匹配的函數(shù)大州。

重寫(override):派生類重寫基類中同名同參數(shù)同返回值的函數(shù)(通常是虛函數(shù),這是推薦的做法)垂谢。同樣重寫的函數(shù)可以有不同的修飾符virtual厦画,public/protected/private。

  • 純虛函數(shù)(抽象類)
  1. 當(dāng)一個類具有一個純虛函數(shù)滥朱,這個類就是抽象類
  2. 抽象類不能實(shí)例化對象
  3. 子類繼承抽象類根暑,必須要實(shí)現(xiàn)純虛函數(shù),如果沒有徙邻,子類也是抽象類
    關(guān)于虛函數(shù)和純虛函數(shù)的具體:https://www.runoob.com/w3cnote/cpp-virtual-functions.html

友元

  • 概念
    類的友元函數(shù)是定義在類外部排嫌,但有權(quán)訪問類的所有私有(private)成員和保護(hù)(protected)成員。盡管友元函數(shù)的原型有在類的定義中出現(xiàn)過缰犁,但是友元函數(shù)并不是成員函數(shù)淳地。采用friend 關(guān)鍵字 表示友元。
  • 友元的兩種表現(xiàn)形式
  1. 友元函數(shù)
  2. 友元類
  • 實(shí)例
class Girl
{
public:
    //友元函數(shù)不能使用this
    friend void modify(Girl *girl, int age);   //聲明的友元函數(shù)
    friend class Boy;    //聲明的友元類

    //friend void Boy::introduce();

    void tell();

private:
    int age = 16;
    string name = "大笑";
};

//girl class的函數(shù)實(shí)現(xiàn)
void Girl::tell() {

    cout << "age == " << age << endl;
}

class Boy
{
public:
    Boy(Girl girl) {
        this->girl = girl;

    }

    ~Boy() {

    }

    void changGirl() {
        girl.age = 28;
        girl.name = "vava";
    }

    //已經(jīng)聲明為友元函數(shù) 可以訪問和修改私有屬性s
    void introduce() {
        cout << "My Girl friend age : " << girl.age << "name = " << girl.name << endl;
    }

public:
    Girl girl;
};

//外部實(shí)現(xiàn)
void modify(Girl *girl, int age) {

    girl->age = age;
}

void main() {
    /*Girl *girl = new Girl();

    modify(girl, 31);

    girl->tell();

    delete girl;*/

    Girl girl;
    Boy boy = Boy(girl);

    boy.introduce();

    boy.changGirl();
    boy.girl.tell();
    boy.introduce();

    system("pause");
}

輸出的結(jié)果


友元類.png

友元函數(shù).png

模板

模板是泛型編程的基礎(chǔ)帅容,泛型編程即以一種獨(dú)立于任何特定類型的方式編寫代碼颇象。

  • 表現(xiàn)形式
  1. 模板函數(shù)
  2. 模板類
  • 實(shí)例
    模板函數(shù)
template <typename T>
void myswap(T& a, T& b) {
    T tmp = 0;
    tmp = a;
    a = b;
    b = tmp;
    cout << "myswap T" << endl;
}

void main() {

    int a = 999;
    int b = 666;

    myswap(a,b);
    cout << "a = "<< a << "b = " <<b << endl;

    char c = '9';
    char v = '6';

    myswap(c, v);

    cout << "c = " << c << "v = " << v << endl;

輸出結(jié)果:


模板函數(shù).png

模板類

template<class  T>
class  A
{
public:
    A(T a) {
        this->a = a;
    }
     ~A() {
     }

protected:
    T a;
};

template <class  T>
class C : public A<T>
{
public:
    
    C(T c, T a) : A<T>(a) {
        this->c = c;
    }

    void tell() {
        cout << "a : " << a << "c " << c << endl;
    }
private:
    T c;
};

void main() {
 C<int>  c(1,2);
 c.tell();
}

輸出結(jié)果:


模板類.png

類型轉(zhuǎn)換

C++ 常見的幾種類型轉(zhuǎn)換

  1. static_cast 普通值類型轉(zhuǎn)換
  2. const_cast 去常量
  3. dynamic_cast 基類和派生類之間的轉(zhuǎn)換
  4. reinterpret_cast 不通用 不常用 函數(shù)指針的轉(zhuǎn)換 (一般在Void * 之間轉(zhuǎn))
    前三種是通用,常用的并徘,第四種屬于不通用遣钳,不常用
  • 實(shí)例
void func(const char c[]) {
    //c[1] = 'a';
    //去掉const 關(guān)鍵字
    char* c_p = const_cast<char *>(c);
    c_p[1] = 'X';
}

class Person {

public:
    virtual void print() {
        cout << "人" << endl;
    }
};

class Man : public Person
{
public:
    void print() {
        cout << "男人" << endl;
    }

    void chasing() {
        cout << "泡妞" << endl;
    }
};

class Woman :public Person
{
public:
    
    void print() {
        cout << "女人" << endl;
    }

    void createBaby() {
        cout << "造小孩" << endl;
    }
};

void funx(Person* obj) {

    //Man *m = (Man *)obj;
    //m->chasing();

    Man *m = dynamic_cast<Man*>(obj);
    if (m != nullptr) {
        m->chasing();
    }
    else {
        cout << "還需要去趟泰國" << endl;
    }
}

void main() {

    int i = 8;
    double d = 9.5;

    //i = (int)d;
    i = static_cast<int> (d);

    char c[] = "hello";
    cout << "c = " << c << endl;
    func(c);
    cout << "c = " << c << endl;

        Man *m = new Man();
    funx(m);

    system("pause");
}

異常捕獲

異常是程序在執(zhí)行期間產(chǎn)生的問題;
異常提供了一種轉(zhuǎn)移程序控制權(quán)的方式。C++ 異常處理涉及到三個關(guān)鍵字:try麦乞、catch蕴茴、throw。 類Java的異常姐直。

  1. throw: 當(dāng)問題出現(xiàn)時荐开,程序會拋出一個異常。這是通過使用 throw 關(guān)鍵字來完成的简肴。
  2. catch: 在您想要處理問題的地方晃听,通過異常處理程序捕獲異常。catch 關(guān)鍵字用于捕獲異常。
  3. try: try 塊中的代碼標(biāo)識將被激活的特定異常能扒。它后面通常跟著一個或多個 catch 塊佣渴。
  • 實(shí)例
void main() {
    try
    {
        int age = 300;
        if (age > 200) {
            throw "xxx";
        }
    }
    catch (int a)
    {
        cout << "int 異常"<<endl;
    }
    catch (char * b) {
        cout << "char b" <<b << endl;
    }
    system("pause");
}

輸出結(jié)果:


異常.png
  • 定義新的異常
class NullPointerException : public exception {

public:

    NullPointerException(char * msg) :exception(msg) {
        
    }
};

void main() {
    try
    {
        int age = 300;
        if (age > 200) {
            throw NullPointerException("pgone");
        }
    }
    catch (int a)
    {
        cout << "int 異常" << endl;
    }
    catch (char * b) {
        cout << "char b" << b << endl;
    }
    catch (NullPointerException msg) {
        
    }
    system("pause");
}

筆記就做到這了。如果有什么問題歡迎指出初斑。

參考文獻(xiàn)

https://www.runoob.com/w3cnote/cpp-virtual-functions.html
https://blog.csdn.net/qq_39477053/article/details/80322260
https://blog.csdn.net/BLUCEJIE/article/details/104474930

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末辛润,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子见秤,更是在濱河造成了極大的恐慌砂竖,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鹃答,死亡現(xiàn)場離奇詭異乎澄,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)测摔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進(jìn)店門置济,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人锋八,你說我怎么就攤上這事浙于。” “怎么了挟纱?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵羞酗,是天一觀的道長。 經(jīng)常有香客問我紊服,道長整慎,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任围苫,我火速辦了婚禮裤园,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘剂府。我一直安慰自己拧揽,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布腺占。 她就那樣靜靜地躺著淤袜,像睡著了一般。 火紅的嫁衣襯著肌膚如雪衰伯。 梳的紋絲不亂的頭發(fā)上铡羡,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天,我揣著相機(jī)與錄音意鲸,去河邊找鬼烦周。 笑死尽爆,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的读慎。 我是一名探鬼主播漱贱,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼夭委!你這毒婦竟也來了幅狮?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤株灸,失蹤者是張志新(化名)和其女友劉穎崇摄,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體慌烧,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡逐抑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了杏死。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡捆交,死狀恐怖淑翼,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情品追,我是刑警寧澤玄括,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站肉瓦,受9級特大地震影響遭京,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜泞莉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一哪雕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧鲫趁,春花似錦斯嚎、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至疫剃,卻和暖如春钉疫,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背巢价。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工牲阁, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留固阁,地道東北人。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓咨油,卻偏偏與公主長得像您炉,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子役电,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評論 2 345