<>内存分区模型
#include<iostream> using namespace std; //栈区数据注意事项:不要返回局部变量的地址
//栈区的数据由编译器管理开辟和释放 int* func(int b) //形参数据也会放在栈区 { b = 100; int a = 10;
//局部变量存放在栈区,栈区的数据在函数执行完后自动释放 return &a; //返回局部变量的地址 } int main() { int * p =
func(1); //接受func()函数的返回值 cout << *p << endl; //第一次可以打印正确的数字,是因为编译器做了保留 cout <<
*p << endl; //第二次这个数据就不再保留了 system("pause"); return 0; }
<>new操作
#include<iostream> using namespace std; int* func() { //在堆区创建一个整形数据
//new返回是该数据类型的指针 int* p = new int(10); return p; } void test01() { int* p = func
(); cout << *p << endl; //堆区数据由程序员管理释放 //释放使用delete delete p; cout << *p << endl
; //内存已释放,再次访问属于非法操作 } void test02() { //创建10个征信数据的数组在堆区 int* arr = new int[10];
for (int i = 0; i < 10; i++) { arr[i] = i + 100; } for (int i = 0; i < 10; i++)
cout<< arr[i] << endl; //释放堆区数组 delete[] arr; } int main() { //test01(); test02(
); }
<>引用
#include<iostream> using namespace std; //值传递 void swap01(int a, int b) { int
temp= a; a = b; b = temp; } //地址传递 void swap02(int *a,int *b) { int temp = *a; *
a= *b; *b = temp; } //引用传递 void swap03(int &a,int &b) { int temp = a; a = b; b =
temp; } int main() { int a = 10, b = 20; swap01(a, b); //形参不会修饰实参,实参不改变 cout <<
"a=" << a << endl; cout << "b=" << b << endl; swap02(&a, &b); //地址传递改变实参 cout <<
"a=" << a << endl; cout << "b=" << b << endl; swap03(a, b); //引用传递形参也可以修饰实参 cout
<< "a=" << a << endl; cout << "b=" << b << endl; }
#include<iostream> using namespace std; //引用做函数返回值 //1. 不要返回局部变量的引用 int& test01
() { int a = 10; //局部变量放在栈区 return a; } //2. 函数的调用可以作为左值 int& test02() { static
int a = 10; //静态变量,存放在全局区,程序结束后由系统释放 return a; } int main() { int& ref = test01(
); cout << ref << endl; cout << ref << endl; test02() = 1000; return 0; }
引用的本质:在C++内部实现是一个指针常量
<>函数重载
#include<iostream> using namespace std; //函数重载满足条件 //1.同一作用域 //2.函数名称相同
//3.函数参数类型不同,或者个数不同,或者顺序不同 //返回值不可以做为函数重载条件 void func() { cout << "xxxx" << endl
; } void func(int a) { cout << "aaaaa" << endl; } void func(double b) { cout <<
"llll" << endl; } void func(int a,double b) { cout << "mmmmm" << endl; } void
func(double a, int b) { cout << "qqqq" << endl; } int main() { func(); func(10);
func(10.1); func(10, 0.1); func(10.1, 10); }
<>类和对象
C++面向对象三大特征:封装,继承,多态
<>封装
公共权限 public 成员类内可以访问,类外可以访问
保护权限 protected 成员类内可以范文,类外不可以访问
私有权限 private 成员类内可以范文,类外不可以访问
保护权限和私有权限在继承中体现出不同。儿子可以访问父亲中的保护内容,儿子不可以访问父亲的私有内容
<>struct和class区别
<>构造函数和析构函数
#include<iostream> using namespace std; //拷贝构造函数调用时机 class Person { public:
Person() { cout << "Person默认构造函数调用" << endl; } Person(int age) { cout <<
"Person含参构造函数调用" << endl; m_Age = age; } Person(const Person & p) { cout <<
"Person拷贝构造函数调用" << endl; m_Age = p.m_Age; } ~Person() { cout << "Person析构函数调用"
<< endl; } int m_Age; }; //1.使用一个已经创建完毕的对象来初始化一个新对象 void test01() { Person p1(20
); Person p2(p1); cout << "年龄为:" << endl; } //2.值传递的方式给函数参数传值 void dowork(
Person p) { } void test02() { Person p; dowork(p); } //3.值方式返回局部对象 Person
dowork2() { Person p1; return p1; } void test03() { Person p = dowork2(); } int
main() { test01(); test02(); test03(); return 0; }
浅拷贝带来的问题:队取得内存重复释放
解决浅拷贝问题:使用深拷贝
<>静态成员
#include<iostream> using namespace std; //静态成员变量 class Person { public:
//所有对象共享同一份数据 //编译阶段就分配内存 //类内声明,类外初始化操作 static int m_A;
//静态成员变量也有访问权限,private中static成员变量不能在类外访问 }; void test01() { Person p; cout << p.
m_A<< endl; Person p1; p1.m_A = 200; cout << p1.m_A << endl; //共享一份内存,数值改变 } int
Person::m_A = 100; //类外初始化 void test02() { //静态成员变量不属于某个对象,所有对象共享同一份数据
//静态成员变量有两种访问方式 //1.通过对象进行访问 Person p; cout << p.m_A << endl; //2.通过类名进行访问 cout
<< Person::m_A << endl; } int main() { //test01(); test02(); return 0; } #
include<iostream> using namespace std; //静态成员函数 //所有对象共享同一个函数 //静态成员函数只能访问静态成员变量
class Person { public: //静态成员函数 static void func() { m_A = 100;
//静态成员函数可以访问静态成员变量 //m_B = 200; 静态成员函数 不可以访问 非静态成员变量 cout << "static void
func函数调用" << endl; } static int m_A; //静态成员变量 int m_B; //非静态成员变量 //静态成员函数也有访问权限
}; void test01() { //1.通过对象名访问 Person p; p.func(); //2.通过类名访问 Person::func(); }
int main() { test01(); return 0; }
<>C++对象模型+this指针
#include<iostream> using namespace std; //成员变量 和 成员函数 分开存储 class Person { int
m_A; //非静态成员变量4字节 static int m_B; //静态成员变量 不属于类对象 void func(){} //非静态成员 }; int
Person::m_B = 0; //静态成员变量 void test01() { Person p; //空对象占内存空间为:1
//C++编译器会给每个空对象也分配一个字节空间,是为了区分空对象占内存位置 //每个空对象也应该有一个独一无二的内存地址 cout << "size of
p =" << sizeof(p) << endl; } void test02() { Person p; cout << "size of p =" <<
sizeof(p) << endl; } int main() { //test01(); test02(); return 0; }
#include<iostream> using namespace std; class Person { public: Person(int age)
{ //this指针指向被调用成员函数所属对象 this->age = age; } void PersonAddAge(Person &p) { this->
age+= p.age; } int age; }; //1.解决名称冲突 void test01() { Person p1(18); cout <<
"p1的年龄为:" << p1.age << endl; } //2.返回对象本身用*this void test02() { Person p1(10);
Personp2(10); p2.PersonAddAge(p1); cout << "p2的年龄为:" << p2.age << endl; } int
main() { //test01(); test02(); return 0; }
#include<iostream> using namespace std; //空指针调用成员函数 class Person { public: void
showClassName() { cout << "this is Person class" << endl; } void showPersonAge()
{ //报错原因是因为传入的指针是为NULL cout << "age=" <<this->m_Age << endl; } int m_Age; };
void test01() { Person* p = NULL; p->showClassName(); p->showPersonAge(); } int
main() { test01(); return 0; }
<>const修饰成员函数
<>友元
#include<iostream> #include<string> using namespace std; class Building {
//goodfriend全局函数是Buiding好朋友,可以访问Buiding中私有成员 friend void goodfriend(Building*
building); public: Building() { m_SittingRoom = "客厅"; m_BedRoom = "卧室"; }
string m_SittingRoom; private: string m_BedRoom; }; //全局函数 void goodfriend(
Building*building) { cout << "好朋友全局函数正在访问:" << building->m_SittingRoom << endl;
cout<< "好朋友全局函数正在访问:" << building->m_BedRoom << endl; //友元可以访问私有成员 } void test01
() { Building building; goodfriend(&building); } int main() { test01(); return 0
; } #include<iostream> using namespace std; class Building; class g { public: g(
); void visit(); //访问Building中的属性 Building* building; }; class Building {
//g类是本类的好朋友,可以访问本类中私有成员 friend class g; public: Building(); string m_SittingRoom
; private: string m_BedRoome; }; //类外写成员函数 Building::Building() { m_SittingRoom
= "客厅"; m_BedRoome = "卧室"; } g::g() { //创建建筑物对象 building = new Building; } void
g::visit() { cout << "好朋友正在访问:" << building->m_SittingRoom << endl; cout <<
"好朋友正在访问:" << building->m_BedRoome << endl; } void test01() { g gg; gg.visit();
} int main() { test01(); return 0; }
<>运算符重载
<>加号重载
#include<iostream> using namespace std; class Person { public: //1.成员函数重载+
/*Person operator+(Person& p) { Person temp; temp.m_A = this->m_A + p.m_A;
temp.m_B = this->m_B + p.m_B; return temp; }*/ int m_A; int m_B; }; //2.全局函数重载+
Personoperator+(Person& p1, Person& p2) { Person temp; temp.m_A = p1.m_A + p2.
m_A; temp.m_B = p1.m_B + p2.m_B; return temp; } void test01() { Person p1; p1.
m_A= 10; p1.m_B = 10; Person p2; p2.m_A = 10; p2.m_B = 10; Person p3 = p1 + p2;
cout<< "p3.m_A=" << p3.m_A << endl; cout << "p3.m_B=" << p3.m_B << endl; } int
main() { test01(); return 0; }
<>继承
下级别成员拥有上一级的共性+自己的特性,继承可以减少代码复杂度
#include<iostream> using namespace std; //继承实现页面 //公共页面 class BasePage { public
: void header() { cout << "123456" << endl; } void footer() { cout << "789987"
<< endl; } void left() { cout << "skjfwej" << endl; } }; //java页面继承 class java :
public BasePage { public: void content() { cout << "java knowledge" << endl; } }
; void test01() { java js; js.content(); js.footer(); js.header(); js.left(); }
int main() { test01(); return 0; }
私有成员只是在继承中被隐藏,仍然会被继承下去,占内存空间
继承中父类子类构造函数和析构函数调用顺序:先调用父类构造函数,子类构造函数,子类析构函数,父类析构函数
#include<iostream> using namespace std; class Base { public: Base() { m_A = 100
; } void func() { cout << "Base -func()" << endl; } int m_A; }; class Son :
public Base { public: Son() { m_A = 200; } void func() { cout << "Son -func()"
<< endl; } int m_A; }; //同名成员属性处理方式 void test01() { Son s; cout << "子类m_A=" <<s.
m_A<< endl; cout << "父类m_A=" << s.Base::m_A << endl; } //同名函数处理方式 void test02()
{ Son s; s.func(); //子类 s.Base::func(); //父类 } int main() { //test01(); test02()
; //子类成员函数调用 return 0; }
<>菱形继承
菱形继承会产生二义性(使用virtual)
#include<iostream> using namespace std; //动物类 class Animal { public: int m_Age;
}; //利用虚继承解决菱形继承问题 //继承之前加上关键字 virtual 变为虚继承 //Animal类称为虚基类 //羊类 class Sheep :
virtual public Animal { }; //驼类 class Tuo :virtual public Animal { }; //羊驼类
class SheepTuo :public Sheep, public Tuo { }; void test01() { SheepTuo st; st.
Sheep::m_Age = 18; st.Tuo::m_Age = 28; //菱形继承,两个父类拥有相同数据,需要加以作用域区分 cout <<
"st.Sheep::m_Age =" << st.Sheep::m_Age << endl; cout << "st.Tuo::m_Age =" << st.
Tuo::m_Age << endl; //菱形继承导致数据有两份,我们只需要一份 } int main() { test01(); return 0; }
<>多态
#include<iostream> using namespace std; //纯虚函数和抽象类 class Base { public:
//纯虚函数(只要有一个纯虚函数,这个类为抽象类) //抽象类特点: //1.无法实例化对象 //2.抽象类的子类,必须重写父类中的纯虚函数 virtual
void func() = 0; }; class Son :public Base { public: virtual void func() { cout
<< "func函数调用" << endl; }; }; void test01() { //Son s; Base* base = new Son; base
->func(); } int main() { test01(); return 0; }
<>构造函数与析构函数
<>文件操作
<>文本文件
#include<iostream> #include<fstream> using namespace std; void test() {
//包含头文件fstream //创建流对象 ofstream ofs; //指定打开方式 ofs.open("testtxt", ios::out);
//写内容 ofs << "姓名:张三" << endl; //关闭文件 ofs.close(); } int main() { test01();
return 0; }
<>二进制文件