一、命名空間
standard:標(biāo)準(zhǔn)命名空間
using namespace std;
命名空間類(lèi)似于java中的包。
- 自定義命名空間
namespace NSP_A{
int a = 9;
struct Teacher{
char name[20];
int age;
};
struct Student{
char name[20];
int age;
};
}
namespace NSP_B{
int a = 12;
//命名空間嵌套
namespace NSP_C{
int c = 90;
}
}
- 使用命名空間
cout << NSP_A::a << endl;
cout << NSP_B::a << endl;
cout << NSP_B::NSP_C::c << endl;
//使用命名空間中的結(jié)構(gòu)體
using NSP_A::Student;
Student t;
t.age = 90;
::為訪問(wèn)修飾符
二、引用
引用是變量的別名(內(nèi)存空間0x00001的別名),指針是變量的地址
int a = 10;
// b是內(nèi)存空間的另一個(gè)別名
//& C++中的引用
int &b = a;
- 使用指針交換數(shù)據(jù)
void swap(int *a, int *b){
int c = 0;
c = *a;
*a = *b;
*b = c;
}
- 使用引用交換數(shù)據(jù)
void swap(int &a, int &b){
int c = 0;
c = a;
a = b;
b = c;
}
引用的主要功能:作為函數(shù)的參數(shù)或返回值,引用必須有值,不能為空
單純給變量取別名沒(méi)有任何意義,作為參數(shù)傳遞,能保證參數(shù)傳遞過(guò)程中不產(chǎn)生副本;
引用可以直接操作變量,指針要通過(guò)取值(*p),間接操作變量,指針的可讀性差。
- 指針的引用代替二級(jí)指針
struct Teacher{
char* name;
int age;
};
void getTeacher(Teacher **p){
Teacher *tmp = (Teacher*)malloc(sizeof(Teacher));
tmp->age = 20;
*p = tmp;
}
//代替二級(jí)指針
//Teacher* &p = (Teacher * *p)
void getTeacher(Teacher* &p){
p = (Teacher*)malloc(sizeof(Teacher));
p->age = 20;
}
- 指針常量/常量指針
指針常量:不改變地址的指針,但是可以修改指針指向的內(nèi)容
int a = 2, b = 3;
int *const p = &a;
p = &b; //不能重新賦值
*p = 4; 可以改變指向的內(nèi)容
常量指針:指向常量的指針,內(nèi)容不能修改
const int *p = &a;
p = &b;
//*p2 = 9; //不能改變內(nèi)容
三、函數(shù)
- C++中函數(shù)可以有默認(rèn)值
void customPrint(int x, int y = 9, int z = 8){
cout << x << endl;
}
- 可變參數(shù)
#include <stdarg.h>
void func(int i,...){
// 可變參數(shù)指針
va_list args_p;
// 開(kāi)始讀取可變參數(shù)類(lèi)型,i是最后一個(gè)固定參數(shù)
va_start(args_p,i);
int a = va_arg(args_p,int);
char b = va_arg(args_p, char);
int c = va_arg(args_p, int);
cout << a << endl;
cout << b << endl;
cout << c << endl;
va_end(args_p);
}
void func(int i,...){
va_list args_p;
va_start(args_p,i);
int value;
// 可變參數(shù)必須是相同類(lèi)型
while (1) {
value = va_arg(args_p,int);
if (value <= 0){
break;
}
cout << value << endl;
}
va_end(args_p);
}
四、類(lèi)
- 定義頭文件
#pragma once
class Person{
public:
int age;
char* name;
public:
void setAge(int age);
int getAge();
void setName(char* name);
char* getName();
};
- 實(shí)現(xiàn)頭文件定義的函數(shù)
#include "Person.h"
void Person::setAge(int age){
this->age = age;
}
int Person::getAge(){
return this->age;
}
void Person::setName(char* name){
this->name = name;
}
char* Person::getName(){
return this->name;
}
- 使用類(lèi)
#include "Person.h"
void main(){
Person person;
person.name= "Jack";
}
- 構(gòu)造函數(shù)
class Person{
private:
char *name;
int age;
public:
//無(wú)參改造函數(shù)(會(huì)覆蓋默認(rèn)的無(wú)參構(gòu)造函數(shù))
Person(){
cout << "無(wú)參構(gòu)造函數(shù)" << endl;
}
// 有參構(gòu)造
Person(char *name, int age){
this->name = name;
this->age = age;
cout << "有參構(gòu)造函數(shù)" << endl;
}
};
- 析構(gòu)函數(shù)
當(dāng)對(duì)象要被系統(tǒng)釋放時(shí)析構(gòu)函數(shù)會(huì)被調(diào)用
~Person(){
cout << "析構(gòu)函數(shù)" << endl;
//釋放內(nèi)存
free(this->name);
}
- 拷貝構(gòu)造函數(shù)
class Person{
private:
char *name;
int age;
public:
Person(char *name, int age){
this->name = name;
this->age = age;
cout << "有參構(gòu)造函數(shù)" << endl;
}
//拷貝構(gòu)造函數(shù)
//默認(rèn)的拷貝構(gòu)造函數(shù)是值拷貝,拷貝的是指針地址
Person(const Person &obj){
this->name = obj.name;
this->age = obj.age;
cout << "拷貝構(gòu)造函數(shù)" << endl;
}
};
void main(){
Person p1("Jack",20);
Person p2 = p1;
}
輸出結(jié)果:
有參構(gòu)造函數(shù)
拷貝構(gòu)造函數(shù)
- 深拷貝
覆蓋默認(rèn)的拷貝構(gòu)造函數(shù),拷貝的是指針指向的內(nèi)容
Person(const Person &obj){
//復(fù)制name屬性
int len = strlen(obj.name);
this->name = (char*)malloc(len+1);
strcpy(this->name,obj.name);
this->age = obj.age;
}
拷貝構(gòu)造函數(shù)被調(diào)用的場(chǎng)景:
- 聲明時(shí)復(fù)制
- 最為參數(shù)傳入,實(shí)參給形參賦值
- 作為函數(shù)返回值返回,給變量初始化賦值
- 構(gòu)造函數(shù)的屬性初始化列表
class Teacher{
private:
char* name;
public:
Teacher(char* name){
this->name = name;
}
~Teacher(){
cout << "析構(gòu)函數(shù)" << endl;
}
char* getName(){
return this->name;
}
};
class Student{
private:
int id;
//屬性對(duì)象
//Teacher t = Teacher("name");
Teacher t1;
Teacher t2;
public:
Student(int id,char *t1_n, char* t2_n) : t1(t1_n), t2(t2_n){
this->id = id;
cout << "Student構(gòu)造函數(shù)" << endl;
}
~Student(){
cout << "Student析構(gòu)函數(shù)" << endl;
}
};
五、new/delete動(dòng)態(tài)內(nèi)存分配
void func(){
//C++
//會(huì)調(diào)用構(gòu)造函數(shù)和析構(gòu)函數(shù)
Teacher *t1 = new Teacher("jack");
cout << t1->getName() << endl;
//釋放
delete t1;
//C的寫(xiě)法,不會(huì)調(diào)用構(gòu)造函數(shù)和析構(gòu)函數(shù)
//Teacher *t2 = (Teacher*)malloc(sizeof(Teacher));
//t2->setName("jack");
//free(t2);
}
數(shù)組類(lèi)型
//C
//int *p1 = (int*)malloc(sizeof(int) * 10);
//p1[0] = 9;
//free(p1);
//C++
int *p2 = new int[10];
p2[0] = 2;
//釋放數(shù)組要加上 []
delete[] p2;
六、靜態(tài)屬性、靜態(tài)方法
class Teacher{
public:
char* name;
//靜態(tài)成員
static int total;
public:
Teacher(char* name){
this->name = name;
cout << "Teacher構(gòu)造函數(shù)" << endl;
}
}
靜態(tài)屬性初始化賦值
int Teacher::total = 9;
初始化完成后使用
Teacher::total++;
靜態(tài)函數(shù)
static void count(){
total++;
cout << total << endl;
}
調(diào)用靜態(tài)函數(shù)
Teacher::count();
七、類(lèi)的大小
class A{
public:
int i;
int j;
int k;
};
class B{
public:
int i;
int j;
int k;
void fun(){
cout << "fun" << endl;
}
};
int main(int argc, const char * argv[]) {
cout<< sizeof(A)<<endl;
cout<< sizeof(B)<<endl;
return 0;
}
輸出結(jié)果:
12
12
C/C++內(nèi)存分區(qū):棧、堆、全局(靜態(tài))、常量去(字符串)、程序代碼區(qū)
普通屬性與結(jié)構(gòu)體相同的內(nèi)存布局
靜態(tài)變量存儲(chǔ)在全局區(qū)
函數(shù)存在程序代碼區(qū)
八、友元函數(shù)
class A{
//友元函數(shù)
friend void modify_i(A *p, int a);
private:
int i;
public:
A(int i){
this->i = i;
}
};
//友元函數(shù)的實(shí)現(xiàn),在友元函數(shù)中可以訪問(wèn)私有的屬性
void modify_i(A *p, int a){
p->i = a;
}
九、友元類(lèi)
class A{
//友元類(lèi)
friend class B;
private:
int i;
public:
A(int i){
this->i = i;
}
};
class B{
public:
//友元類(lèi)可以訪問(wèn)A中的任何成員
void accessAny(){
a.i = 30;
}
private:
A a;
};
十、運(yùn)算符重載
class Point{
public:
int x;
int y;
public:
Point(int x = 0, int y = 0){
this->x = x;
this->y = y;
}
void myprint(){
cout << x << "," << y << endl;
}
//成員函數(shù)運(yùn)算符重載
Point operator+(Point &p2){
Point tmp(this->x + p2.x, this->y + p2.y);
return tmp;
}
};
//重載+運(yùn)算符
Point operator+(Point &p1, Point &p2){
Point tmp(p1.x + p2.x, p1.y + p2.y);
return tmp;
}
//重載-運(yùn)算符
Point operator-(Point &p1, Point &p2){
Point tmp(p1.x - p2.x, p1.y - p2.y);
return tmp;
}
十一、繼承
class Human{
public:
void say(){
cout << "say" << endl;
}
protected:
char* name;
int age;
};
//子類(lèi)
class Man : public Human{
public:
void work(){
cout << "work" << endl;
}
private:
char* brother;
};
int main(int argc, const char * argv[]) {
Man man;
man.say();
Human *p = &man;
p->say();
return 0;
}
帶有參構(gòu)造函數(shù)的繼承
class Human{
public:
Human(char* name, int age){
this->name = name;
this->age = age;
}
void say(){
cout << "say" << endl;
}
protected:
char* name;
int age;
};
class Man : public Human{
public:
Man(char *brother, char *s_name, int s_age, char *h_name, int h_age) : Human(s_name, s_age), h(h_name,h_age){
this->brother = brother;
}
void work(){
cout << "work" << endl;
}
private:
char* brother;
Human h;
};
多繼承
//人
class Person{
};
//公民
class Citizen{
};
//多繼承
class Student : public Person, public Citizen{
};
十二、多態(tài)
- 虛函數(shù)實(shí)現(xiàn)多態(tài)
//Plane.h
class Plane{
public:
virtual void fly();
virtual void land();
};
//Plane.cpp
void Plane::fly(){
cout << "起飛" << endl;
}
void Plane::land(){
cout << "著陸" << endl;
}
// Helicopter.h
class Helicopter : public Plane{
virtual void fly();
virtual void land();
};
// Helicopter.cpp
void Jet::fly(){
cout << "直升機(jī)起飛" << endl;
}
void Jet::land(){
cout << "直升機(jī)著陸" << endl;
}
- 純虛函數(shù)(抽象類(lèi))
當(dāng)一個(gè)類(lèi)具有純虛函數(shù)時(shí),這個(gè)類(lèi)就是抽象類(lèi)。抽象類(lèi)不能實(shí)例化對(duì)象。子類(lèi)繼承抽象類(lèi)必須實(shí)現(xiàn)純虛函數(shù),如果沒(méi)有子類(lèi)也是抽象類(lèi)
class Shape{
public:
//純虛函數(shù)
virtual void sayArea() = 0;
};
class Circle : public Shape{
public:
Circle(int r){
this->r = r;
}
void sayArea(){
cout << "圓的面積" << (3.14 * r * r) << endl;
}
private:
int r;
};
十三、模板函數(shù)(泛型)
void myswap(int& a,int& b){
int tmp = 0;
tmp = a;
a = b;
b = tmp;
}
void myswap(char& a, char& b){
char tmp = 0;
tmp = a;
a = b;
b = tmp;
}
上面兩個(gè)函數(shù)業(yè)務(wù)邏輯一樣,數(shù)據(jù)類(lèi)型不一樣。
template <typename T>
void myswap(T& a, T& b){
T tmp = 0;
tmp = a;
a = b;
b = tmp;
}