1 内存模型-内存四区
1.1 程序运行前
#include <iostream>
using namespace std;
//全局变量
int c = 10;
int d = 10;
//const修饰的全局变量
const int c_a = 10;
int main()
{
//全局区
//全局变量,静态变量,常量
//创建普通局部变量
int a = 10;
int b = 10;
cout << "局部变量a地址" << (int)&a << endl;
cout << "局部变量b地址" << (int)&b << endl;
cout << "全局变量c地址" << (int)&c << endl;
cout << "全局变量d地址" << (int)&d << endl;
//静态变量 在普通变量前加static,属于静态变量
static int e = 10;
static int f = 10;
cout << "静态变量e地址" << (int)&e << endl;
cout << "静态变量f地址" << (int)&f << endl;
//常量
//字符串常量
cout << "字符串常量的地址" << (int)&"hello world" << endl;
//const修饰的变量
cout << "const修饰的全局变量c_a的地址" << (int)&c_a << endl;
//const修饰的局部变量
const int c_b = 10;
cout << "const修饰的局部变量c_b的地址" << (int)&c_b << endl;
}
运行结果:
局部变量a地址223344228
局部变量b地址223344260
全局变量c地址-170926080
全局变量d地址-170926076
静态变量e地址-170926072
静态变量f地址-170926068
字符串常量的地址-170938984
const修饰的全局变量的地址-170939312
const修饰的局部变量的地址223344292
1.2程序运行后
#include <iostream>
using namespace std;
//栈区数据的注意事项 ---不要返回局部变量地址
//栈区的数据由编译器管理开辟和释放
int * func()
{
int a = 10; //局部变量 存放在栈区,栈区在函数执行完后自动释放掉
return &a; //返回局部变量地址
}
int main()
{
int* p;
p = func();
cout << *p << endl;
cout << *p << endl;
}
1.3 new 操作符
#include <iostream>
using namespace std;
//new 的基本用法
int* func()
{
//在堆区创建整型数据
//new返回的是该数据类型的指针;
int* p = new int(10);
return p;
}
void test01()
{
int* p = func();
cout << *p << endl;
delete p;
//cout << *p << endl; 内存已经释放,再次访问就是非法操作,会报错
}
//在堆区利用new开辟数组
void test02()
{
//创建10整型的数组,在堆区
int* arr = new int[10]; //10代表数组有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();
}
运行结果:
10
100
101
102
103
104
105
106
107
108
109
2 引用
2.1 引用的基本使用
#include <iostream>
using namespace std;
int a = 10;
//引用的基本语法
//数据类型 &别名=原名
int &b = a;
int main()
{
b = 20;
cout << a;
}
运行结果:
20
2.2 引用的注意事项
#include <iostream>
using namespace std;
int main()
{
int a = 10;
//引用必须初始化
int& b = a;
//引用在初始化后,不可以更改
int c = 20;
b = c; //赋值操作,而不是更改
cout << "a=" << a << endl;
cout << "b=" << b << endl;
cout << "c=" << c << endl;
}
运行结果:
a=20
b=20
c=20
2.3 引用做函数参数
#include <iostream>
using namespace std;
//交换函数
//值传递
void mySwap01(int a, int b)
{
int temp = a;
a = b;
b = temp;
}
//地址传递
void mySwap02(int* a, int* b)
{
int temp = *a;
*a = *b;
*b = temp;
}
//引用传递
void mySwap03(int &a, int &b)
{
int temp = a;
a = b;
b = temp;
}
int main()
{
int a = 10, b = 20;
mySwap01(a, b);
cout << "mySwap01:a=" << a << endl;
cout << "mySwap01:b=" << b << endl;
a = 10, b = 20;
//值传递不会修改实参
mySwap02(&a,&b);
cout << "mySwap02:a=" << a << endl;
cout << "mySwap02:b=" << b << endl;
a = 10, b = 20;
//地址传递会修改实参
mySwap03(a, b);
cout << "mySwap03:a=" << a << endl;
cout << "mySwap03:b=" << b << endl;
//引用传递会修改实参
}
运行结果:
mySwap01:a=10
mySwap01:b=20
mySwap02:a=20
mySwap02:b=10
mySwap03:a=20
mySwap03:b=10
2.4 引用做函数返回值
#include <iostream>
using namespace std;
//不要返回局部变量的引用
int& test01()
{
int a = 10; //局部变量存放在栈区
return a;
}
//函数的调用可以作为左值
int& test02()
{
static int a = 10; //静态变量存放在全局区
return a;
}
int main()
{
int &a = test01();
cout << a << endl; //第一次正确是因为编译器做了一次保留
cout << a << endl;
int& b = test02();
cout << b << endl;
test02() = 20; //如果函数的返回值是引用,这个函数的调用可以作为左值
cout << b << endl;
}
运行结果:
10
10
10
20
2.5 引用的本质
指针常量(指针是常量);----常量指针(常量的指针);
指针常量:该指针是常量,是一个指向不可改,值可改的指针
常量指针:指向常量的指针,是一个指向可改 ,值不可改的指针
#include <iostream>
using namespace std;
void func(int& ref)
{
ref = 20; //ref是引用。转换为*ref=100
}
int main()
{
int a = 10;
int& ref = a; //自动转换为int *const ref = &a;
ref = 20; //转换为 *ref=20;
cout << "a:=" << a << endl;
cout << "ref:=" << ref << endl;
}
运行结果:
a:=20
ref:=20
2.6 常量引用
#include <iostream>
using namespace std;
//打印数据
void showvalue(const int& val)
{
//val = 1000;
cout << "val=" << val << endl;
}
int main()
{
//int a = 10;
//加上const之后,编译器将代码修改为
//int temp=10;const int & ref = temp;
const int& ref = 10; //引用必须是一块合法的内存空间
//ref = 20; //加上const之后变为只读,不可以修改
int a = 100;
showvalue(a);
cout <<"a=" <<a << endl;
}
运行结果:
val=100
a=100
3 函数提高
3.1 函数默认参数
#include <iostream>
using namespace std;
//如果我们自己传入数据,就用自己的数据。如果没用,那么用默认值
int func(int a, int b = 20, int c = 30)
{
return a + b + c;
}
//int func2(int a,int b=10,int c)
//{
// return a + b + c;
//}
//注意事项
//1 如果某个位置已经有了默认参数,那么从这个位置往后,从左到右都必须有默认值
//2 如果函数声明有默认参数,函数实现就不能有默认参数
// 声明和实现只能有一个默认参数
//int func2(int a = 10, int b = 10);
int main()
{
cout << func(10, 20, 30) << endl;
cout << func(10, 30) << endl;
cout << func(10) << endl;
// cout << func2(10,10,10) << endl;
}
//int func2(int a = 10, int b = 10)
//{
// return a + b;
//}
3.2 函数占位符
#include <iostream>
using namespace std;
//占位参数
void func(int a, int)
{
cout << "1" << endl;
}
int main()
{
//func(10);// 没有占位参数不可以调用该函数
func(10,1);
}
4 类和对象
4.1 构造函数和析构函数
4.2 函数的分类以及调用
#include <iostream>
using namespace std;
// 拷贝构造函数调用时机
// 1 使用一个已经创建完毕的对象来初始化一个新对象
// 2 值传递的方式给函数参数传值
// 3 值方式返回局部变量
class Person
{
public:
int show()
{
return age;
}
Person()
{
age = 0;
cout << "Preson默认构造函数调用" << endl;
}
Person(int a)
{
age = a;
cout << "Preson有参构造函数调用" << endl;
}
~Person()
{
cout << "Preson析构函数调用" << endl;
}
//拷贝构造函数
Person(const Person& p)
{
age = p.age;
cout << "Person拷贝构造函数调用" << endl;
}
private:
int age;
};
//调用
void test01()
{
// 1 括号法
//Person p1;
//Person p2(10);
//Person p3(p2);
//cout << "p1的年龄=" << p1.show() << endl;
//cout << "p2的年龄=" << p2.show() << endl;
//cout << "p3的年龄=" << p3.show() << endl;
// 注意事项
// 调用默认构造函数时候,不要加()
// 因为下面这行代码,编译器会认为是一个函数的声明
// Person p(); 不会认为在创建对象
// void func();
// 2 显示法
//Person p1;
//Person p2 = Person(10); //有参构造
//Person p3 = Person(p2); //拷贝构造
//Person(10); //匿名对象 特点:当前行执行结束后,系统会立即释放掉
//不要利用拷贝构造函数来初始化匿名对象
//Person(p3); // 编译器会认为 Person(p3)==Person p3; 重定义!
// 3 隐式转换法
//Person p = 10; // 相当于Person P==(10); 有参构造
//Person p1 = Person (p); //拷贝构造函数
}
int main()
{
test01();
}
4.3 拷贝构造函数的调用时机
#include <iostream>
using namespace std;
// 拷贝构造函数调用时机
// 1 使用一个已经创建完毕的对象来初始化一个新对象
// 2 值传递的方式给函数参数传值
// 3 值的方式返回局部变量
class Person
{
public:
int show()
{
return age;
}
Person()
{
age = 0;
cout << "Person默认构造函数调用" << endl;
}
Person(int age)
{
this->age = age;
cout << "Person有参构造函数调用" << endl;
}
~Person()
{
cout << "Person析构函数调用" << endl;
}
Person(const Person &p)
{
age = p.age;
cout << "Person拷贝构造函数调用" << endl;
}
private:
int age;
};
// 1 使用一个已经创建完毕的对象来初始化一个新对象
void test01()
{
Person p1(20);
Person p2(p1);
cout << "p1的年龄=" << p1.show() << endl;
cout << "p2的年龄=" << p2.show() << endl;
}
// 2 值传递的方式给函数参数传值
void dowork(Person p)
{
}
void test02()
{
Person p;
dowork(p); //拷贝构造函数
}
// 3 值的方式返回局部变量
Person dowork02()
{
Person p1;
cout << (int*)&p1 << endl;
return p1;
}
void test03()
{
Person p = dowork02();
cout << (int*)&p << endl;
}
int main()
{
test01();
test02();
test03();
}
4.4 深拷贝与浅拷贝
#include <iostream>
using namespace std;
// 深拷贝与浅拷贝
class Person
{
public:
int show()
{
return age;
}
void change(int a)
{
age = a;
}
Person()
{
age = 0;
cout << "Person的默认构造函数调用" << endl;
}
Person(int age,int height)
{
this->age = age;
this->height=new int(height);
cout << "Person的有参构造函数调用" << endl;
}
~Person()
{
//析构代码,将堆区开辟的数据做释放操作
if (height != NULL)
{
delete height;
height = NULL;
}
cout << "Person的析构函数调用" << endl;
}
Person(const Person& p)
{
cout << "Person拷贝构造函数的调用" << endl;
age = p.age;
//height = p.height; 编译器默认实现就是这行代码
//深拷贝操作
height = new int(*p.height);
}
int age; //年龄
int* height; //身高
};
void test01()
{
Person p1(18,160);
cout << "p1的年龄为:" << p1.show() << " p1的身高为:" << *p1.height << endl;
cout << "p1地址为:" << (int*)&p1.age << endl;
Person p2(p1);
cout << "p2的年龄为:" << p2.show() << " p2的身高为:" << *p2.height << endl;
cout << "p2地址为:" << (int*)&p2.age << endl;
p1.change(20);
cout << "p2的年龄为:" << p2.show() << endl;
}
int main()
{
test01();
}
运行结果:
Person的有参构造函数调用
p1的年龄为:18 p1的身高为:160
p1地址为:00000068254FF4F8
Person拷贝构造函数的调用
p2的年龄为:18 p2的身高为:160
p2地址为:00000068254FF528
p2的年龄为:18
Person的析构函数调用
Person的析构函数调用
4.5 类对象作为类成员
#include <iostream>
#include <string>
using namespace std;
//类对象作为类成员
class phone
{
public:
phone(string pname)
{
this->pname = pname;
cout << "创建手机" << endl;
}
//型号
string pname;
};
class Person
{
public:
Person(string name, string pname):m_name(name),m_phone(pname)
{
cout << "创建人类" << endl;
}
//姓名
string m_name;
//手机
phone m_phone;
};
void test01()
{
Person p("张三", "MAX");
cout << p.m_name <<"拿着" << p.m_phone.pname << endl;
}
int main()
{
test01();
}
//先创建“零件”再创建“主体”
4.6 静态成员
#include <iostream>
using namespace std;
//静态成员变量
class Person
{
public:
//所有对象都共享同一份数据
//在编译阶段就分配了内存
//类内声明,类外初始化
static void func()
{
cout << "static void func调用" << endl;
}
static int m_A;
};
void test01()
{
Person p;
cout << p.m_A;
Person p2;
p2.m_A = 200;
cout << p.m_A;
}
void test02()
{
Person p;
//通过对象访问
cout << p.m_A << endl;
//痛过类名进行访问
cout << Person::m_A << endl;
}
//静态成员函数
//所有对象共享一个函数
//静态成员函数只能访问静态成员变量
void test03()
{
//通过对象访问
Person p;
p.func();
//通过类名访问
Person::func();
}
int Person::m_A = 100;
int main()
{
test01();
}
4.7 this指针的用途
#include <iostream>
using namespace std;
class Person
{
public:
//用于解决名称冲突
Person(int age)
{
this->age = age;
}
Person& PersonAddAge(Person& p)
{
this->age += p.age;
return *this;
}
int age;
};
void test()
{
Person p1(10);
Person p2(10);
//链式思想
p2.PersonAddAge(p1).PersonAddAge(p1);
cout << p2.age << endl;
}
int main()
{
test();
}
4.8 const修饰成员函数
#include <iostream>
using namespace std;
//常函数
class Person
{
public:
//this指针的本质是指针常量,指针的指向是不可以修改的
//在成员函数后加const,修饰的是this指针,让指针指向的值也不可以修改
void showPerson() const
{
this->m_B = 100;
//this->m_A = 100;
//this=NULL;//this指针是不可以修改指向
}
void func()
{
m_A = 100;
}
int m_A;
mutable int m_B;// 特殊变量,即使在常函数中,也可以修改这个值,加关键字 mutable
};
void test01()
{
Person p;
p.showPerson();
}
//常对象
void test02()
{
const Person p;//在对象前加const ,变为常对象
//p.m_A = 100;
p.m_B = 100;//m_B是特殊值,在常对象下可以修改
//常对象只能调用常函数
p.showPerson();
//p.func();
}
int main()
{
std::cout << "Hello World!\n";
}
4.9 友元
4.9.1 全局函数做友元
#include <iostream>
#include <string>
using namespace std;
class Building
{
friend void goodGay(Building* building);//可以访问私有成员
public:
Building()
{
m_SittingRoom = "客厅";
m_BedRoom = "卧室";
}
string m_SittingRoom;
private:
string m_BedRoom;
};
//全局函数
void goodGay(Building* building)
{
cout << "好基友全局函数 正在访问:" << building->m_SittingRoom << endl;
cout << "好基友全局函数 正在访问:" << building->m_BedRoom << endl;
}
void test()
{
Building buiding;
goodGay(&buiding);
}
int main()
{
test();
}
4.9.2 类做友元
#include <iostream>
#include <string>
using namespace std;
class Building
{
friend class goodGay;
public:
Building();
string m_SittingRoom;
private:
string m_BedRoom;
};
class goodGay
{
public:
goodGay();
void visit(); //参观函数访问Building中的属性
Building * building;
};
//类外写成员函数
Building::Building()
{
m_SittingRoom = "客厅";
m_BedRoom = "卧室";
}
goodGay::goodGay()
{
//创建建筑物对象
building = new Building;
}
void goodGay::visit()
{
cout << "好基友类正在访问:" << building->m_SittingRoom << endl;
cout << "好基友类正在访问:" << building->m_BedRoom << endl;
}
void test()
{
goodGay gg;
gg.visit();
}
int main()
{
test();
}
4.9.3 成员函数做友元
#include <iostream>
#include <string>
using namespace std;
class building;
class goodgay
{
public:
void visit();//让visit函数可以访问biuding中私有成员
void visit2();//让visit2不可以访问biuding中私有成员
goodgay();
building * Building;
};
class building
{
friend void goodgay::visit();//告诉编译器 goodday下的visit成员函数作为本类的好朋友,可以访问私有内容
public:
building()
{
sittingroom = "客厅";
bedroom = "卧室";
}
string sittingroom;
private:
string bedroom;
};
void goodgay::visit()
{
cout << "visit函数正在访问:" << Building->sittingroom << endl;
cout << "visit函数正在访问:" << Building->bedroom << endl;
}
void goodgay::visit2()
{
cout << "visit函数正在访问:" << Building->sittingroom << endl;
//cout << "visit函数正在访问:" << Building->bedgroom << endl;
}
void test01()
{
goodgay gg;
gg.visit();
gg.visit2();
}
goodgay::goodgay()
{
Building = new building;
}
int main()
{
test01();
}
4.10 运算符重载
4.10.1 加号运算符重载
#include <iostream>
using namespace std;
//加号运算符
class Person
{
public:
//成员函数重载加号
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;
}
Person operator+(int n)
{
Person temp;
temp.m_A = this->m_A + n;
temp.m_B = this->m_B + n;
return temp;
}
int m_A, m_B;
};
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.operator+(p2);
//全局函数本质调用
//Person p3=operator+(p1,p2);
Person p3 = p1 + p2;
//运算符重载可以发声函数重载
Person p4 = p1 + 100;
cout << "p3.m_A=" << p3.m_A << endl;
cout << "p3.m_B=" << p3.m_B << endl;
cout << "p4.m_A=" << p4.m_A << endl;
cout << "p4.m_B=" << p4.m_B << endl;
}
//全局函数重载+号
//Person operator+(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;
//}
int main()
{
test01();
}
4.10.2 左移运算符重载
#include <iostream>
using namespace std;
class Person
{
friend void test01();
friend ostream& operator<<(ostream& cout, Person& p);
public:
//利用成员函数重载左移运算符 p.operator<<(cout) 简化版本 p<<cout
//不会利用成员函数<<运算符,因为无法实现 cout 在左侧
//void operator<<(Person &p)
//{
//
//}
private:
int m_A, m_B;
};
//只能利用全局函数重载左移运算符
ostream &operator<<(ostream &cout,Person &p) //本质是 operator<<(cout,p)简化cout<<p
{
cout << "m_A" << p.m_A << "m_B" << p.m_B;
return cout;
}
void test01()
{
Person p;
p.m_A = 10;
p.m_B = 10;
cout << p << "hello" << endl;
}
int main()
{
test01();
}
4.10.3 递增运算符重载
#include <iostream>
using namespace std;
//重载递增运算符
//自定义整型
class MyInt
{
friend ostream& operator<<(ostream& cout, MyInt& myint);
public:
MyInt()
{
m_num = 0;
}
//重载前置++运算符
MyInt& operator++()
{
//先进行++运算
m_num++;
//再返回自身
return *this;
}
//重载后置++运算符
MyInt operator++(int) //括号中的int代表占位参数,可以用于区分前置和后置递增
{
//先记录当时结果
MyInt temp = *this;
//后递增
m_num++;
return temp;
}
private:
int m_num;
};
void test01()
{
MyInt myint;
cout << ++myint << endl;
cout << myint << endl;
}
void test02()
{
MyInt myint;
myint++;
cout << myint << endl;
}
ostream& operator<<(ostream& cout, MyInt & myint)
{
cout << myint.m_num;
return cout;
}
int main()
{
test02();
}
//前置返回引用,后置返回值
4.10.4 赋值运算符重载
#include <iostream>
using namespace std;
//赋值运算符重载
class Person
{
public:
Person(int age)
{
m_age = new int(age);
}
~Person()
{
if (m_age != NULL)
{
delete m_age;
m_age = NULL;
}
}
//重载赋值运算符
Person & operator=(Person &p)
{
//编译器提供的浅拷贝
//m_age = p.m_age;
//应该先判断是否有属性再堆区,如果有先释放干净,然后再深拷贝
if (m_age != NULL)
{
delete m_age;
m_age = NULL;
}
//深拷贝
m_age = new int(*p.m_age);
//返回对象本身
return *this;
}
int* m_age;
};
void test01()
{
Person p1(18);
Person p2(20);
Person p3(30);
p3 = p2 = p1;
p1 = p2; //赋值操作
cout << "p1的年龄为:" << *p1.m_age << endl;
cout << "p2的年龄为:" << *p2.m_age << endl;
cout << "p3的年龄为:" << *p3.m_age << endl;
}
int main()
{
test01();
int a = 10;
int b = 20;
int c = 30;
c = b = a;
cout << "a=" << a << endl;
cout << "b=" << b << endl;
cout << "c=" << c << endl;
}
运行结果:
p1的年龄为:18
p2的年龄为:18
p3的年龄为:18
a=10
b=10
c=10
D:\Study\赋值运算符重载\x64\Debug\赋值运算符重载.exe (进程 29848)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .
4.10.5 关系运算符重载
#include <iostream>
#include <string>
using namespace std;
//重载关系运算符
class Person
{
public:
Person(string name,int age)
{
m_name = name;
m_age = age;
}
//重载==号
bool operator==(Person& p)
{
if (this->m_age == p.m_age && this->m_name == p.m_name)
{
return true;
}
return false;
}
string m_name;
int m_age;
};
void test01()
{
Person p1("Tom", 18);
Person p2("Tom", 18);
if (p1 == p2)
{
cout << "p1和p2是相等的" << endl;
}
}
int main()
{
test01();
}
运行结果:
p1和p2是相等的
4.10.6 函数调用运算符重载
#include <iostream>
#include <string>
using namespace std;
//函数调用运算符重载
//打印处处类
class MyPrint
{
public:
//重载函数调用运算符
void operator()(string test)
{
cout << test << endl;
}
};
void test01()
{
MyPrint myprint;
myprint("1");//由于使用起来非常想函数调用,因此称为仿函数
}
void print(string a)
{
cout << a << endl;
}
//仿函数非常的灵活,没有固定的写法
//加法类
class MyAdd
{
public:
int operator()(int num_1,int num_2)
{
return num_1 + num_2;
}
};
void test02()
{
MyAdd add;
cout << add(10, 20) << endl;
//匿名函数对象
cout << MyAdd()(10, 20) << endl;//匿名对象执行完后立即被释放
}
int main()
{
test01();
print("a");
test02();
}
运行结果:
1
a
30
30
4.11 继承
4.11.1 继承基本语法
#include <iostream>
using namespace std;
//普通实现页面
//Java 页面
//class Java
//{
//public:
// void header()
// {
// cout << " 首页,公开课,登录,注册...(公共头部)" << endl;
// }
// void footer()
// {
// cout << " 帮助中心,交流合作,站内地图...(公共底部)" << endl;
// }
// void left()
// {
// cout << " Java Python C++ ...(公共分类列表)" << endl;
// }
// void content()
// {
// cout << " Java学科视频" << endl;
// }
//};
Python 页面
//class Python
//{
//public:
// void header()
// {
// cout << " 首页,公开课,登录,注册...(公共头部)" << endl;
// }
// void footer()
// {
// cout << " 帮助中心,交流合作,站内地图...(公共底部)" << endl;
// }
// void left()
// {
// cout << " Java Python C++ ...(公共分类列表)" << endl;
// }
// void content()
// {
// cout << " Python学科视频" << endl;
// }
//};
C++ 页面
//class Cpp
//{
//public:
// void header()
// {
// cout << " 首页,公开课,登录,注册...(公共头部)" << endl;
// }
// void footer()
// {
// cout << " 帮助中心,交流合作,站内地图...(公共底部)" << endl;
// }
// void left()
// {
// cout << " Java Python C++ ...(公共分类列表)" << endl;
// }
// void content()
// {
// cout << " Cpp学科视频" << endl;
// }
//};
//继承实现页面
//继承好处:减少重复代码
//公共页面
class BasePage
{
public:
void header()
{
cout << " 首页,公开课,登录,注册...(公共头部)" << endl;
}
void footer()
{
cout << " 帮助中心,交流合作,站内地图...(公共底部)" << endl;
}
void left()
{
cout << " Java Python C++ ...(公共分类列表)" << endl;
}
};
//Java 页面
class Java :public BasePage
{
public:
void content()
{
cout << "Java 学科视频" << endl;
}
};
//Python 页面
class Python :public BasePage
{
public:
void content()
{
cout << "Python 学科视频" << endl;
}
};
//C++ 页面
class Cpp :public BasePage
{
public:
void content()
{
cout << "C++ 学科视频" << endl;
}
};
void test01()
{
cout << " Java 下载视频页面如下:" << endl;
Java ja;
ja.header();
ja.footer();
ja.left();
ja.content();
cout << "------------------------" << endl;
cout << " Python 下载视频页面如下:" << endl;
Java py;
py.header();
py.footer();
py.left();
py.content();
cout << "------------------------" << endl;
cout << " C++ 下载视频页面如下:" << endl;
Cpp cp;
cp.header();
cp.footer();
cp.left();
cp.content();
}
int main()
{
test01();
}
4.11.2 继承方式
4.11.3 继承中的对象模型
#include <iostream>
using namespace std;
//继承中的对像模型
class Base
{
public:
int m_A;
protected:
int m_B;
private:
int m_C;
};
class Son :public Base
{
public:
int m_D;
};
//利用开发人员命令提示工具查看对象模型
//条转盘符 F:
//跳转文件路径 cd 具体路径下
//查看命名
// c1 /d1 reportSingleClassLayout类名 文件名
void test01()
{
//16
//父类中所有非静态成员都会被子类继承下去
//父类中私有成员属性是被编译器给隐藏了,因此是访问不到的,但是确实是是被继承下去了
cout << "size of Son=" << sizeof(Son) << endl;
}
int main()
{
test01();
}
4.11.4 继承中构造和析构顺序
#include <iostream>
using namespace std;
class Base
{
public:
Base()
{
cout << "Base构造函数" << endl;
}
~Base()
{
cout << "Base析构函数" << endl;
}
};
class Son :public Base
{
public:
Son()
{
cout << "Son构造函数" << endl;
}
~Son()
{
cout << "Son析构函数" << endl;
}
};
int main()
{
Son a;
}
运行结果:
Base构造函数
Son构造函数
Son析构函数
Base析构函数
4.11.5 继承中同名成员函数处理方式
#include <iostream>
using namespace std;
//继承中同名成员处理
class Base
{
public:
Base()
{
m_A = 100;
}
void func()
{
cout << "Base-func()调用" << endl;
}
void func(int a)
{
cout << "Base-func(int a)调用" << 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 << " Son下的m_A=" << s.m_A << endl;
//如果通过子类对象访问父类中同名成员,需要加作用域
cout << " Base下的m_A=" << s.Base::m_A << endl;
}
void test02()
{
Son s;
s.func();//直接调用调用的是子类中的同名成员
s.Base::func();//调用父类要加作用域
//子类同名函数会隐藏父类所有同名函数,如果想调用必须加作用域
}
int main()
{
test02();
}
4.11.6 同名静态函数处理
#include <iostream>
using namespace std;
//继承中同名静态成员处理方式
class Base
{
public:
static void func()
{
cout << "Base - static void func()调用" << endl;
}
static int m_A;
};
int Base::m_A = 100;
class Son :public Base
{
public:
static void func()
{
cout << "Son - static void func()调用" << endl;
}
static int m_A;
};
int Son::m_A = 200;
//同名静态成员属性
void test01()
{
Son s;
//通过对象访问数据
cout << "通过对象访问" << endl;
cout << "Son 下的 m_A=" << s.m_A << endl;
cout << "Base 下的 m_A=" << s.Base::m_A << endl;
//通过类名访问数据
cout << "通过类名访问" << endl;
cout << "Son 下的 m_A=" << Son::m_A << endl;
//第一个::代表通过类名方式访问 第二个::代表访问父类作用域下
cout << "Base 下的 m_A=" << Son::Base::m_A << endl;
}
//静态成员函数
void test02()
{
//通过对象访问
cout << "通过对象访问" << endl;
Son s;
s.func();
s.Base::func();
//通过类名访问
cout << "通过类名访问" << endl;
Son::func();
Son::Base::func();
}
int main()
{
test02();
}
4.11.7 多继承语法
#include <iostream>
using namespace std;
class Base1
{
public:
Base1()
{
m_A = 100;
}
int m_A;
};
class Base2
{
public:
Base2()
{
m_B = 100;
}
int m_B;
};
//子类 需要继承Base1和Base2
//语法 :class 子类:继承方式 父类1,继承方式 父类2...
class Son :public Base1, public Base2
{
public:
Son()
{
m_C = 300;
m_D = 400;
}
int m_C, m_D;
};
void test01()
{
Son s;
cout << "sizeof Son" << sizeof(Son) << endl;
}
int main()
{
test01();
}
4.11.8 菱形继承
#include <iostream>
using namespace std;
//动物类
class Animal
{
public:
int m_age;
};
//利用虚继承可以解决菱形继承的问题
//在继承之前加 Virtual 面为虚继承
//Animal类称为虚基类
//羊类
class Sheep :virtual public Animal
{
};
//驼类
class camel :virtual public Animal
{
};
//羊驼类
class SheepCamel :public Sheep, public camel
{
};
void test01()
{
SheepCamel st;
st.Sheep::m_age = 18;
st.camel::m_age = 28;
//当菱形继承,两大父类拥有相同的数据,需要加已作用域区分
cout << "st.Sheep::m_age =" << st.Sheep::m_age << endl;
cout << "st.camel::m_age =" << st.camel::m_age << endl;
cout << "st.m_age =" << st.m_age << endl;
//这份数据有一份就可以了,菱形继承导致数据有两份,浪费资源
}
int main()
{
test01();
}
4.12 多态
4.12.1 多态的基本概念
#include <iostream>
using namespace std;
//多态
//动物类
class Animal
{
public:
//虚函数
virtual void speak()
{
cout << "动物在说话" << endl;
}
};
//猫类
class Cat :public Animal
{
public:
//重写 函数返回值类型 函数名 参数列表 完全相同
void speak()
{
cout << "小猫在说话" << endl;
}
};
//狗类
class Dog :public Animal
{
public:
//重写 函数返回值类型 函数名 参数列表 完全相同
void speak()
{
cout << "小狗在说话" << endl;
}
};
//执行说话的函数
//地址早绑定 在编译阶段确定函数地址
//如果想执行让猫说话,那么这个地址就不能提前绑定,需要在运行阶段进行绑定,地址晚绑定
//动态多态满足条件
//1 有继承关系
//2 子类要重写父类的虚函数
//动态多态只用
//父类的指针或引用 执行子类对象
void dospeak(Animal& animal) // Animal & animal=cat;
{
animal.speak();
}
void test01()
{
Cat cat;
dospeak(cat);
Dog dog;
dospeak(dog);
}
int main()
{
test01();
}
运行结果:
小猫在说话
小狗在说话
4.12.2 多态的原理刨析
#include <iostream>
using namespace std;
//多态
//动物类
class Animal
{
public:
//虚函数
virtual void speak()
{
cout << "动物在说话" << endl;
}
};
//猫类
class Cat :public Animal
{
public:
//重写 函数返回值类型 函数名 参数列表 完全相同
void speak()
{
cout << "小猫在说话" << endl;
}
};
//狗类
class Dog :public Animal
{
public:
//重写 函数返回值类型 函数名 参数列表 完全相同
void speak()
{
cout << "小狗在说话" << endl;
}
};
//执行说话的函数
//地址早绑定 在编译阶段确定函数地址
//如果想执行让猫说话,那么这个地址就不能提前绑定,需要在运行阶段进行绑定,地址晚绑定
//动态多态满足条件
//1 有继承关系
//2 子类要重写父类的虚函数
//动态多态只用
//父类的指针或引用 执行子类对象
void dospeak(Animal& animal) // Animal & animal=cat;
{
animal.speak();
}
void test01()
{
Cat cat;
dospeak(cat);
Dog dog;
dospeak(dog);
}
void test02()
{
cout << "sizeof Animal =" << sizeof(Animal) << endl;
}
int main()
{
test02();
}
4.12.3 多态案例-计算机类
#include <iostream>
using namespace std;
//普通实现
class Calculator
{
public:
int getResult(string oper)
{
if (oper == "+")
{
return m_num1 + m_num2;
}
else if (oper == "-")
{
return m_num1 - m_num2;
}
else if (oper == "*")
{
return m_num1 * m_num2;
}
}
//如果想扩展新的功能,需要修改源码
//在真实的开发中 提倡 开闭原则
//开闭原则:对扩展进行开发,对修改进行关闭
int m_num1;
int m_num2;
};
//利用多态实现
//多态好处:
//1 组织结构清晰
//2 可读性强
//3 对于前期和后期扩展以及维护性高
class AbstractCalculator
{
public:
virtual int getResult()
{
return 0;
}
int m_num1;
int m_num2;
};
//加法计算器类
class AddCaculator :public AbstractCalculator
{
public:
int getResult()
{
return m_num1 + m_num2;
}
};
class SubCaculator :public AbstractCalculator
{
int getResult()
{
return m_num1 - m_num2;
}
};
class MulCaculator :public AbstractCalculator
{
int getResult()
{
return m_num1 * m_num2;
}
};
void test01()
{
//创建一个计算器对象
Calculator c;
c.m_num1 = 10;
c.m_num2 = 10;
cout << c.m_num1 << "+" << c.m_num2 << "=" << c.getResult("+") << endl;
cout << c.m_num1 << "-" << c.m_num2 << "=" << c.getResult("-") << endl;
cout << c.m_num1 << "*" << c.m_num2 << "=" << c.getResult("*") << endl;
}
void test02()
{
//多态使用条件
//父类指针或引用指向子类对象
//加法运算563 1
AbstractCalculator* abc = new AddCaculator;
abc->m_num1 = 10;
abc->m_num2 = 20;
cout << abc->m_num1 << "+" << abc->m_num2 << "=" << abc->getResult() << endl;
//用完后记得销毁
delete abc;
abc = new SubCaculator;
abc->m_num1 = 10;
abc->m_num2 = 20;
cout << abc->m_num1 << "-" << abc->m_num2 << "=" << abc->getResult() << endl;
}
int main()
{
test02();
}
4.12.4 纯虚函数和抽象类
#include <iostream>
using namespace std;
//纯虚函数和抽象类
class Base
{
public:
//纯虚函数
//只要有一个春旭函数,这个类就叫做抽象类
//抽象类特点:
//1 无法实例化对象
//2 抽象类的子类 必须要重写符类中的纯虚函数,否则也属于抽象类
virtual void func() = 0;
};
class Son :public Base
{
public:
void func()
{
cout << "func 函数调用" << endl;
};
};
void test01()
{
//Base b;//抽象类不能实例化对象
//new base;//抽象类不能实例化对象
//Son s;//子类必须重写父类纯虚函数,否则无法实例化对象
Base* base = new Son;
base->func();
}
int main()
{
test01();
}
4.12.5 多态案例-制作饮品
#include <iostream>
using namespace std;
//多态案例 制作饮品
class AbstractDrinking
{
public:
//煮水
virtual void Boil() = 0;
//冲泡
virtual void Brew() = 0;
//倒入杯中
virtual void PourInCup() = 0;
//加入辅助的佐料
virtual void PutSomething() = 0;
//制作饮品
void makeDrink()
{
Boil();
Brew();
PourInCup();
PutSomething();
}
};
//制作咖啡
class Coffee :public AbstractDrinking
{
public:
//煮水
virtual void Boil()
{
cout << "煮水" << endl;
}
//冲泡
virtual void Brew()
{
cout << "冲泡咖啡" << endl;
}
//倒入杯中
virtual void PourInCup()
{
cout << "倒入杯中" << endl;
}
//加入辅助的佐料
virtual void PutSomething()
{
cout << "加如牛奶和糖" << endl;
}
};
//制作茶水
class Tea :public AbstractDrinking
{
public:
//煮水
virtual void Boil()
{
cout << "煮水" << endl;
}
//冲泡
virtual void Brew()
{
cout << "冲泡茶叶" << endl;
}
//倒入杯中
virtual void PourInCup()
{
cout << "倒入杯中" << endl;
}
//加入辅助的佐料
virtual void PutSomething()
{
cout << "加柠檬和枸杞" << endl;
}
};
void doWork(AbstractDrinking* abs)
{
abs->makeDrink();
delete abs;
}
void test01()
{
//制作咖啡
doWork(new Coffee);
//制作茶水
doWork(new Tea);
}
int main()
{
test01();
}
运行结果:
煮水
冲泡咖啡
倒入杯中
加如牛奶和糖
煮水
冲泡茶叶
倒入杯中
加柠檬和枸杞
4.12.6 虚析构和纯虚析构
#include <iostream>
using namespace std;
//虚析构和纯虚析构
class Animal
{
public:
Animal()
{
cout << "Anima构造函数调用" << endl;
}
//利用虚析构可以解决父类释放子类对象是不干净问题
//virtual~Animal()
//{
// cout << "Animal析构函数调用" << endl;
//}
virtual ~Animal() = 0;
virtual void speak() = 0;
};
Animal:: ~Animal()
{
cout << "Animal纯虚析构函数调用" << endl;
}
class Cat :public Animal
{
public:
Cat() {};
Cat(string name)
{
cout << "Cat的构造函数调用" << endl;
m_name = new string(name);
}
virtual void speak()
{
cout <<*m_name<< "小猫在说话" << endl;
}
~Cat()
{
if (m_name != NULL)
{
cout << "Cat的析构函数调用" << endl;
delete m_name;
m_name = NULL;
}
}
string * m_name;
};
void test01()
{
Animal* animal = new Cat("Tom");
animal->speak();
//父类的指针在析构时候,不会调用子类的析构函数,导致子类如果有堆区属性,出现内存泄露
delete animal;
}
int main()
{
test01();
}
运行结果:
Anima构造函数调用
Cat的构造函数调用
Tom小猫在说话
Cat的析构函数调用
Animal纯虚析构函数调用
4.12.7 多态案例-电脑组装
#include <iostream>
using namespace std;
//抽象不同零件类
//抽象CPU类
class CPU
{
public:
//抽象的计算函数
virtual void calculate() = 0;
};
//抽象GPU类
class GPU
{
public:
//抽象的显示函数
virtual void display() = 0;
};
//抽象RAM类
class RAM
{
public:
//抽象的存储函数
virtual void storage() = 0;
};
//电脑类
class Computer
{
public:
Computer(CPU* cpu, GPU* gpu, RAM* ram)
{
m_cpu=cpu;
m_gpu=gpu;
m_ram=ram;
}
~Computer()
{
if (m_cpu != NULL)
{
delete m_cpu;
m_cpu = NULL;
}
if (m_gpu != NULL)
{
delete m_gpu;
m_gpu = NULL;
}
if (m_ram != NULL)
{
delete m_ram;
m_ram = NULL;
}
}
void work()
{
//让零件工作起来,调用接口
m_cpu->calculate();
m_gpu->display();
m_ram->storage();
}
private:
CPU* m_cpu;//CPU零件指针
GPU* m_gpu;//GPU零件指针
RAM* m_ram;//RAM零件指针
};
//具体厂商
//Intel厂商
class IntelCPU :public CPU
{
public:
virtual void calculate()
{
cout << "Intel的CPU开始计算了!" << endl;
}
};
class IntelGPU :public GPU
{
public:
virtual void display()
{
cout << "Intel的GPU开始显示了!" << endl;
}
};
class IntelRAM :public RAM
{
public:
virtual void storage()
{
cout << "Intel的RAM开始存储了!" << endl;
}
};
//AMD厂商
class AMDCPU :public CPU
{
public:
virtual void calculate()
{
cout << "AMD的CPU开始计算了!" << endl;
}
};
class AMDGPU :public GPU
{
public:
virtual void display()
{
cout << "AMD的GPU开始显示了!" << endl;
}
};
class AMDRAM :public RAM
{
public:
virtual void storage()
{
cout << "AMD的RAM开始存储了!" << endl;
}
};
void test01()
{
//创建第一台电脑的零件
CPU* intelCPU = new IntelCPU;
GPU* intelGPU = new IntelGPU;
RAM* intelRAM = new IntelRAM;
CPU* amdCPU = new AMDCPU;
GPU* amdGPU = new AMDGPU;
RAM* amdRAM = new AMDRAM;
//第一台电脑组装
Computer* computer1 = new Computer(intelCPU, intelGPU, intelRAM);
cout << "第一台电脑开始工作" << endl;
computer1->work();
delete computer1;
cout << "----------------------" << endl;
//第二台电脑组装
Computer* computer2 = new Computer(amdCPU, amdGPU, amdRAM);
cout << "第二台电脑开始工作" << endl;
computer2->work();
delete computer2;
cout << "----------------------" << endl;
//第三台电脑组装
Computer* computer3 = new Computer(new AMDCPU, new AMDGPU, new IntelRAM);
cout << "第三台电脑开始工作" << endl;
computer3->work();
delete computer3;
cout << "----------------------" << endl;
}
int main()
{
test01();
}
运行结果:
第一台电脑开始工作
Intel的CPU开始计算了!
Intel的GPU开始显示了!
Intel的RAM开始存储了!
----------------------
第二台电脑开始工作
AMD的CPU开始计算了!
AMD的GPU开始显示了!
AMD的RAM开始存储了!
----------------------
第三台电脑开始工作
AMD的CPU开始计算了!
AMD的GPU开始显示了!
Intel的RAM开始存储了!
----------------------
5 文件操作
5.1 文本文件
5.1.1 写文件
#include <iostream>
#include <fstream>
using namespace std;
//文本文件 写文件
int main()
{
//1 包含头文件 fstream
//2 创建流对象
ofstream ofs;
//3 指定打开方式
ofs.open("test.txt", ios::out);
//4 写内容
ofs << "姓名:张三" << endl;
ofs << "姓别:男" << endl;
ofs << "年龄:18" << endl;
//5 关闭文件
ofs.close();
}
5.1.2 读文件
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
//文本文件 读文件
void test01()
{
//1 包含头文件
//2 创建流对象
ifstream ifs;
//3 打开文件 并且判断是否打开成功
ifs.open("test.txt", ios::in);
if(!ifs.is_open())
{
cout << "文件打开失败" << endl;
return;
}
//4 读数据
//第一种
/*char buf[1024] = { 0 };
while (ifs >> buf)
{
cout << buf << endl;
}*/
//第二种
/*char buf[1024] = { 0 };
while (ifs.getline(buf, 1024))
{
cout << buf << endl;
}*/
//第三种
/*string buf;
while (getline(ifs, buf))
{
cout << buf << endl;
}*/
//第四种
//char c;
//while (c == ifs.get() != EOF)//EOF end of file
//{
// cout << c << endl;
//}
//5 关闭文件
ifs.close();
}
int main()
{
test01();
}
5.2 二进制文件
5.2.1 写文件
#include <iostream>
#include <fstream>
using namespace std;
//二进制文件 写文件
class Person
{
public:
char m_name[64];
int m_age;
};
void test01()
{
//1 包含头文件
//2 创建流对象
ofstream ofs("person.txt", ios::out | ios::binary);
//3 打开文件
//ofs.open("person.txt",ios::out | ios::binary)
//4 写文件
Person p = { "张三",18 };
ofs.write((const char*)&p, sizeof(Person));
//5 关闭文件
ofs.close();
}
int main()
{
test01();
}
5.2.2 读文件
#include <iostream>
#include <fstream>
using namespace std;
//二进制文件 读文件
class Person
{
public:
char m_name[64];
int m_age;
};
void test01()
{
//1 包含头文件
//2 创建流对象
ifstream ifs("person.txt", ios::out | ios::binary);
//3 打开文件 判断文件是否打开成功
ifs.open("person.txt", ios::in | ios::binary);
if (!ifs.is_open())
{
cout << "文件打开失败" << endl;
return;
}
//4 读文件
Person p;
ifs.read((char*)&p, sizeof(Person));
cout << "姓名:" << p.m_name << "年龄:" << p.m_age << endl;
//5 关闭文件
ifs.close();
}
int main()
{
test01();
}
6 模板
6.1 函数模板
#include <iostream>
using namespace std;
//函数模板
//两个整型交换函数
void swapInt(int& a, int& b)
{
int temp = a;
a = b;
b = temp;
}
//交换两个浮点型函数
void swapDouble(double& a, double& b)
{
double temp = a;
a = b;
b = temp;
}
//函数模板
template<typename T> //声明一个模板,告诉编译器后面代码中紧跟着的T不要报错,T是一个通用的数据类型
void mySwap(T& a, T& b)
{
T temp=a;
a = b;
b = temp;
}
void test01()
{
int a = 10, b = 20;
//利用函数模板交换
//两种方式使用函数模板
//1 自动类型推导
mySwap(a, b);
//2 显示指定类型
mySwap<int>(a, b);
cout << "a=" << a << endl;
cout << "b=" << b << endl;
double c = 1.1;
double e = 2.2;
swapDouble(c, e);
}
int main()
{
test01();
}
6.2 函数模板注意事项
#include <iostream>
using namespace std;
//函数模板注意事项
template<typename T> //typename可以替换class
void mySwap(T& a, T& b)
{
T temp = a;
a = b;
b = temp;
}
//1 自动类型推导,必须推导出一致的数据类型T才可以使用
void test01()
{
int a = 10;
int b = 20;
char c = 'c';
mySwap(a, b);//正确!
//mySwap(a, c);//错误!推导不出来
}
//2 模板必须要确定出T的数据类型,才可以使用
template<class T>
void func()
{
cout << "func 调用" << endl;
}
void test02()
{
func<int>();
}
int main()
{
test02();
}
6.3 函数模板案例
#include <iostream>
using namespace std;\
//时下按通用 对数组进行排序的函数
//规则 从大到小
//算法 选择
//测试 char 数组, int 数组
template<class T>
void mySwap(T& a, T& b)
{
T temp = a;
a = b;
b = temp;
}
//排序算法
template<class T>
void mySort(T arr[],int len)
{
for (int i = 0; i < len; i++)
{
int max = i; //认定最大值的下标
for (int j = i + 1; j < len; j++)
{
if (arr[max] < arr[j])
{
max = j;
}
}
if (max != i)
{
//交换msx和i的元素
mySwap(arr[max], arr[i]);
}
}
}
//打印数组模板
template<class T>
void printArray(T arr[], int len)
{
for (int i=0; i < len; i++)
{
cout << arr[i] << " ";
}
cout << endl;
}
void test01()
{
//测试 char 数组
char charArr[] = "badcfe1";
int num = sizeof(charArr) / sizeof(char);
mySort(charArr, num);
printArray(charArr, num);
}
int main()
{
test01();
}
7 STL
7.1 STL的诞生
7.2 STL基本概念
7.3 STL六大组件
7.4 STL中容器,算法,迭代器
7.5 容器算法迭代器初识
7.5.1 vector存放内置数据类型
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
void myPrint(int val)
{
cout << val << endl;
}
void test01()
{
//创建一个vector容器,数组
vector<int> v;
//向容器中插入数据
v.push_back(10);
v.push_back(20);
v.push_back(30);
v.push_back(40);
//通过迭代器访问容器中的数据
vector<int>::iterator itBegin = v.begin();//起始迭代器 指向容器中第一个元素
vector<int>::iterator itEnd = v.end();//结束迭代器 指向容器中最后一个元素的下一个位置
//第一种的遍历方式
while (itBegin != itEnd)
{
cout << *itBegin << endl;
itBegin++;
}
//第二种的遍历方式
for (vector<int>::iterator it = v.begin(); it != v.end();it++)
{
cout << *it << endl;
}
//第三种的遍历方式 利用STL中的遍历算法
for_each(v.begin(),v.end(), myPrint);
}
int main()
{
test01();
}
7.5.2 vector存放自定义数据类型
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Person
{
public:
Person(string name, int age)
{
this->m_name = name;
this->m_age = age;
}
string m_name;
int m_age;
};
void test01()
{
vector<Person>v;
Person p1("aaa", 10);
Person p2("bbb", 20);
Person p3("ccc", 30);
Person p4("ddd", 40);
Person p5("eee", 50);
//向容器中添加数据
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
v.push_back(p4);
v.push_back(p5);
//遍历容器中的数据
for (vector<Person>::iterator it = v.begin(); it != v.end(); it++)
{
cout << "姓名:" << (*it).m_name << endl;
cout << "年龄:" << (*it).m_age << endl;
}
//存放自定义数据类型 指针
}
void test02()
{
vector<Person*>v;
Person p1("aaa", 10);
Person p2("bbb", 20);
Person p3("ccc", 30);
Person p4("ddd", 40);
Person p5("eee", 50);
//向容器中添加数据
v.push_back(&p1);
v.push_back(&p2);
v.push_back(&p3);
v.push_back(&p4);
v.push_back(&p5);
//遍历容器
for (vector<Person*>::iterator it=v.begin();it!=v.end();it++)
{
cout << "姓名:" << (*it)->m_name << "年龄:" << (*it)->m_age << endl;
}
}
int main()
{
test02();
}