典型的C++面向對象編程
元素
(1)頭文件hpp中類的定義
(2)源文件cpp中類的實現(構造函數、析構函數、方法)
(3)主程序
案例
(1)用C++來編程“人一天的生活”
(2)“人”的屬性:name、age、male
(3)“人”的方法:eat、work(coding/shopping)、sleep
(4)人的生活:eat1->work->eat2->work->sleep
實戰中,一般一個cpp和一個hpp文件配對,描述一個class,class的名字和文件名相同的。
.h 文件
namespace MAN{
class testperson {public://屬性string name;int age;bool male; //性別 男性 ture//方法void eat(void);void work(void);void sleep(void);testperson(/* args */);~testperson();
};
.c 文件
using namespace MAN;
testperson::testperson(/* args */) {}testperson::~testperson() {}void testperson::eat(void) { cout << this->name << "-eat" << endl; }
void testperson::work(void) {if (this->male == 1) {cout << name << "-coding" << endl;} else {cout << name << "-shopping" << endl;}
}
void testperson::sleep(void) { cout << name << "-sleep" << endl; }int test() {testperson xioahong; //局部變量 分配在棧上testperson *xiaoming =new testperson(); // 動態內存 分配在自由內存空間,其實就是對堆上// 自己管理內存xiaoming->name = "jiajia";xiaoming->age = 99;xiaoming->male = true;xiaoming->eat();xiaoming->work();xiaoming->eat();xiaoming->work();xiaoming->sleep();return 0;
}
代碼:
testperson xiaoming = new testperson();
報錯:
error: conversion from ‘testperson*’ to non-scalar type ‘testperson’
requested 1071 | new testperson();version from ‘testperson*’ to
non-scalar type ‘testperson’ requested 1071 | new testperson();
修改:
testperson *xiaoming = new testperson();
-
C++面向對象式編程總結
(1)整個工作分為2大塊:一個是建模和編寫類庫,一個是使用類庫來編寫主程序完成任務。
(2)有些人只負責建模和編寫類庫,譬如開發opencv的人。
(3)有些人直接調用現成類庫來編寫自己的主任務程序,譬如使用opencv分析一張圖片中有沒有電動車
(4)難度上不確定,2個都可能很難或者很簡單。 -
C++學習的三重境界
(1)學習C++第一重境界就是語法層面,先學會如何利用C++來建模、來編程,學習語法時先別解決難度大問題。
(2)學習C++第二重境界是解決問題層面,學習如果理解并調用現成類庫來編寫主程序解決問題。
(3)學習C++第三重境界是編寫類庫和sample給別人用,需要基礎好且有一定架構思維。
在構造和析構函數中使用動態內存
析構函數的使用
(1)析構函數在對象對銷毀時自動調用,一般有2種情況
(2)用new分配的對象,用delete顯式析構
(3)分配在棧上的對象,當棧釋放時自動析構
(4)普通情況下析構函數都是空的,因為不必做什么特別的事情
class testperson {public://屬性string name;int age;bool male; //性別 男性 ture//方法void eat(void);void work(void);void sleep(void);testperson(/* args */);~testperson();
};
testperson::testperson(/* args */) { cout << name << "1" << endl; }testperson::~testperson() { cout << name << "2" << endl; }void testperson::eat(void) { cout << this->name << "-eat" << endl; }
void testperson::work(void) {if (this->male == 1) {cout << name << "-coding" << endl;} else {cout << name << "-shopping" << endl;}
}
void testperson::sleep(void) { cout << name << "-sleep" << endl; }int test0625006() {testperson *xiaohong1 =new testperson(); // 動態內存 分配在自由內存空間,其實就是對堆上// 自己管理內存xiaohong1->name = "jiajia";xiaohong1->age = 99;xiaohong1->male = true;xiaohong1->eat();xiaohong1->work();xiaohong1->eat();xiaohong1->work();xiaohong1->sleep();delete xiaohong1; //添加才會執行析構函數testperson xiaohong; //局部變量 分配在棧上xiaohong.name = "meimei";xiaohong.age = 99;xiaohong.male = true;xiaohong.eat();xiaohong.work();xiaohong.eat();xiaohong.work();xiaohong.sleep();return 0;
}
- 在class中使用動態內存變量
(1)什么情況下用動態內存?需要大塊內存,且需要按需靈活的申請和釋放,用棧怕爆、用全局怕浪費和死板時
(2)在class person中增加一個int *指針,用于指向一個int類型元素的內存空間
(3)在構造函數中分配動態內存
(4)在析構函數中回收動態內存
(5)將動態內存從int變量升級到int數組變量
(6)實戰中C++常用的動態內存往往是容器vector那些,課程第3部分會講到
class testperson {public://屬性string name;int age;bool male; //性別 男性 tureint *pint;//方法void eat(void);void work(void);void sleep(void);testperson(/* args */);~testperson();
};
testperson::testperson(/* args */) {this->pint = new int(99);//分配、初始化cout << name << "1" << endl;
}testperson::~testperson() {cout << name << "2" << endl;delete this->pint;//回收
}void testperson::eat(void) { cout << this->name << "-eat" << endl; }
void testperson::work(void) {if (this->male == 1) {cout << name << "-coding" << endl;} else {cout << name << "-shopping" << endl;}cout << "this->pint:" << *(this->pint) << endl;//使用
}
void testperson::sleep(void) { cout << name << "-sleep" << endl; }int test0625006() {testperson *xiaohong1 =new testperson(); // 動態內存 分配在自由內存空間,其實就是對堆上// 自己管理內存xiaohong1->name = "jiajia";xiaohong1->age = 99;xiaohong1->male = true;xiaohong1->eat();xiaohong1->work();xiaohong1->eat();xiaohong1->work();xiaohong1->sleep();delete xiaohong1; //添加才會執行析構函數testperson xiaohong; //局部變量 分配在棧上xiaohong.name = "meimei";xiaohong.age = 99;xiaohong.male = true;xiaohong.eat();xiaohong.work();xiaohong.eat();xiaohong.work();xiaohong.sleep();return 0;
}
申請更多的空間
class testperson {public://屬性string name;int age;bool male; //性別 男性 tureint *pint;char *pchar;//方法void eat(void);void work(void);void sleep(void);testperson(/* args */);~testperson();
};
testperson::testperson(/* args */) {this->pint = new int(99); //分配、初始化this->pchar = new char[20]; //分配、初始化cout << name << "1" << endl;
}testperson::~testperson() {cout << name << "2" << endl;delete this->pint; //回收delete[] this->pchar; //回收
}void testperson::eat(void) { cout << this->name << "-eat" << endl; }
void testperson::work(void) {if (this->male == 1) {cout << name << "-coding" << endl;} else {cout << name << "-shopping" << endl;}cout << "this->pint:" << *(this->pint) << endl; //使用for (size_t i = 0; i < 20; i++) {*(this->pchar) = 'a'+ i;cout << "this->pchar:" << *(this->pchar) << endl; //使用}
}
void testperson::sleep(void) { cout << name << "-sleep" << endl; }int test0625006() {testperson *xiaohong1 =new testperson(); // 動態內存 分配在自由內存空間,其實就是對堆上// 自己管理內存xiaohong1->name = "jiajia";xiaohong1->age = 99;xiaohong1->male = true;xiaohong1->eat();xiaohong1->work();xiaohong1->eat();xiaohong1->work();xiaohong1->sleep();delete xiaohong1; //添加才會執行析構函數testperson xiaohong; //局部變量 分配在棧上xiaohong.name = "meimei";xiaohong.age = 99;xiaohong.male = true;xiaohong.eat();xiaohong.work();xiaohong.eat();xiaohong.work();xiaohong.sleep();return 0;
}
用valgrind工具查看內存泄漏
(1)valgrind工具介紹:參考:https://blog.csdn.net/u012662731/article/details/78652651
(2)安裝:
sudo apt-get install valgrind
(ubuntu16.04 X64)sudo apt-get install valgrind
(3)編譯程序:主要是添加-g參數便于調試時有行號 g++ person.cpp main.cpp -g -o apptest
(4)使用:valgrind --tool=memcheck --leak-check=full --show-reachable=yes --trace-children=yes ./app
- valgrind和Cmake工程結合
1、在CMakeLists.txt文件添加
SET(CMAKE_BUILD_TYPE "Debug")
2、使用下面語句生成了日志3_g,將test換成你自己的工程名稱
valgrind --leak-check=yes --log-file=3_g ./build/test
總結:
學會分文件創建一個類,并且使用起來
學會使用valgrind查看日志
學習記錄,侵權聯系刪除。
來源:朱老師物聯網大課堂