传智播客C++视频学习笔记(3)
#include<iostream> using namespace std; //内存分区模型 //代码区,存放二进制代码,由操作系统进行管理 //全局区,存放全局变量、静态变量、常量(字符串常量和const修饰的全局常量) //栈区,存放函数参数值、局部变量等,由编译器自动分配释放 //堆区,由程序员分配和释放,若程序员不,程序结束时由操作系统回收 //内存四区意义,不同区域存放的数据赋予不同的生命周期,给我们更大的灵活编程 //程序运行前:代码区,全局区 //程序运行后:栈区,堆区 //全局变量 int g_a = 10; int g_b = 10; //const修饰的全局常量 const int c_g_a = 10; const int c_g_b = 10; int main() { //局部变量 int a = 10; int b = 10; cout << "局部变量地址为 " << (int)&a << endl; cout << "局部变量地址为 " << (int)&b << endl; cout << "全局变量地址为 " << (int)&g_a << endl; cout << "全局变量地址为 " << (int)&g_b << endl; //静态变量 static int s_a = 10; static int s_b = 10; cout << "静态变量地址为 " << (int)&s_a << endl; cout << "静态变量地址为 " << (int)&s_b << endl; //字符串常量 string s1 = "s1"; string s2 = "s2"; cout << "字符串常量地址为 " << (int)&s1 << endl; cout << "字符串常量地址为 " << (int) & "s2" << endl; //const修饰的全局常量 cout << "const修饰的全局常量 " << (int)&c_g_a << endl; cout << "const修饰的全局常量 " << (int)&c_g_b << endl; //const修饰的局部常量 const int c_l_a = 10; const int c_l_b = 10; cout << "const修饰的局部常量 " << (int)&c_l_a << endl; cout << "const修饰的局部常量 " << (int)&c_l_b << endl; system("pause"); return 0; }
#include<iostream> using namespace std; int* func(int b) //形参数据也会存放在栈区 { int a = 10; return &a; //不要返回局部变量的地址,局部变量存放在栈区,栈区开辟的数据由编译器自动释放 } int main() { int* p = func(1); cout << *p << endl; //第一次打印正确,是因为编译器做了保留 cout << *p << endl; //第二次打印错误 system("pause"); return 0; }
#include<iostream> using namespace std; int* func() { int* p = new int(10); //利用new关键字可以将数据开辟到堆区 return p; //指针本质上也是局部变量,放在栈上,但指针保存的数据是放在堆区 } //栈:int* p 0x0011 //堆:0x0011 10 int main() { int* p = func(); cout << *p << endl; cout << *p << endl; system("pause"); return 0; }
#include<iostream> using namespace std; int* func() { int* p = new int(10); return p; } int main() { int* p = func(); cout << *p << endl; cout << *p << endl; delete p; //cout << *p << endl; //报错 cout << "------------------------------------" << endl; //堆区开辟数组 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; system("pause"); return 0; }
#include<iostream> using namespace std; int main() { int a = 10; int& b = a; //给变量起别名 cout << "a = " << a << endl; cout << "b = " << b << endl; b = 100; cout << "a = " << a << endl; cout << "b = " << b << endl; system("pause"); return 0; }
#include<iostream> using namespace std; int main() { int a = 10; int b = 20; //引用必须初始化 //int& c; //引用初始化后不可以改变 int& c = a; c = b; //这是赋值操作 cout << "a = " << a << endl; cout << "b = " << b << endl; cout << "c = " << c << endl; system("pause"); return 0; }
#include<iostream> using namespace std; //值传递 void mySwap01(int a, int b) { int temp = a; a = b; b = temp; } //地址传递 void mySwap02(int* p1, int* p2) { int temp = *p1; *p1 = *p2; *p2 = temp; } //引用传递 void mySwap03(int& a, int& b) { int temp = a; a = b; b = temp; } int main() { int a = 10; int b = 20; //mySwap01(a, b); //mySwap02(&a, &b); mySwap03(a, b); cout << "a = " << a << endl; cout << "b = " << b << endl; system("pause"); return 0; }
#include<iostream> using namespace std; //返回局部变量引用 int& test01() { int a = 10; return a; } //返回静态变量引用 int& test02() { static int a = 100; return a; } int main() { //不要返回局部变量引用 int& ref = test01(); cout << "ref = " << ref << endl; cout << "ref = " << ref << endl; //返回静态变量引用 int& ref2 = test02(); cout << "ref2 = " << ref2 << endl; cout << "ref2 = " << ref2 << endl; //函数调用作为左值,必须返回引用 test02() = 1000; cout << "ref2 = " << ref2 << endl; cout << "ref2 = " << ref2 << endl; system("pause"); return 0; }
#include<iostream> using namespace std; void func(int& ref) { ref = 100; } int main() { int a = 10; //引用本质是在C++内部实现一个指针常量 //指针常量,指针指向不可以修改,即引用不可以修改 //int* const ref = &a; int& ref = a; //*ref = 20; ref = 20; cout << "a = " << a << endl; cout << "ref = " << ref << endl; func(a); cout << "a = " << a << endl; cout << "ref = " << ref << endl; system("pause"); return 0; }
#include<iostream> using namespace std; //常量引用通常用来修饰形参 void showValue(const int& v) { //v += 10; cout << "v = " << v << endl; } int main() { //常量引用主要用来修饰形参,防止误操作,即防止形参改变实参 //错误,需要加一个const修饰 //int& ref = 10; //int temp = 10; const int& ref = temp; const int& ref = 10; //ref = 100; //不可以修改 //函数中利用常量引用防止误操作修改实参 int a = 10; showValue(a); system("pause"); return 0; }
#include<iostream> using namespace std; //函数参数某个位置有默认值,那么从这个位置往后,从左到右,必须都要有默认值 int func(int a, int b = 10, int c = 20) { return a + b + c; } //如果函数声明有默认值,函数实现就不能有默认值,二者冲突 ///函数声明 int func2(int a = 10, int b = 20); //函数实现 int func2(int a, int b) { return a + b; } int main() { cout << "return = " << func(20, 20) << endl; //60 cout << "return = " << func2(20, 20) << endl; //40 system("pause"); return 0; }
#include<iostream> using namespace std; //函数占位参数,也可以有默认值 void func(int a, int) { cout << "this is func" << endl; } int main() { func(10, 10); system("pause"); return 0; }
#include<iostream> using namespace std; //函数重载条件: //同一作用域下 //函数名称相同 //函数参数类型不同、个数不同、顺序不同 //注:函数返回值不同不可以作为函数重载的满足条件 void func() { cout << "func()调用" << endl; } void func(int a) { cout << "func(int a)调用" << endl; } void func(double d) { cout << "func(double d)调用" << endl; } void func(int a, double d) { cout << "func(int a, double d)调用" << endl; } void func(double d, int a) { cout << "func(double d, int a)调用" << endl; } int main() { func(); func(1); func(1.1); func(1, 1.1); func(1.1, 1); system("pause"); return 0; }
#include<iostream> using namespace std; //引用作为重载条件 void func(int& a) { cout << "func(int& a)调用" << endl; } void func(const int& a) { cout << "func(const int& a)调用" << endl; } //函数重载碰到函数默认参数 void func2(int a, int b = 10) { cout << "func2(int a, int b = 10)调用" << endl; } void func2(int a) { cout << "func2(int a)调用" << endl; } int main() { int a = 10; func(a); //调用无const func(10); //调用有const func2(100, 100); //此处填一个参数会产生歧义 system("pause"); return 0; }
#include<iostream> using namespace std; //类和对象 //面向对象三大特征:封装、继承、多态 //万物皆对象,对象有属性和行为 //车类,车 //? //设计一个圆类求其周长 const double PI = 3.14; class Circle { public: int r; double zhouChang() { return 2 * PI * r; } }; int main() { Circle c; c.r = 10; cout << "圆的周长 = " << c.zhouChang() << endl; system("pause"); return 0; }
#include<iostream> using namespace std; class Student { public: string m_name; int m_id; void setName(string name) { m_name = name; } void setId(int id) { m_id = id; } void showStudent() { cout << "name = " << m_name << " " << "id = " << m_id << endl; } }; int main() { Student s; s.m_name = "张三"; s.m_id = 100; //s.setName("李四"); s.showStudent(); system("pause"); return 0; }
#include<iostream> using namespace std; //public 公共权限,类内类外均可以访问 //protected 保护权限,类内可以访问类外不可以访问 //private 私有权限,类内可以访问类外不可以访问 class Preson { public: string m_name; protected: string m_car; private: int m_passWord; }; int main() { Preson p; p.m_name = "张三"; //p.m_car; //p.m_passWord; system("pause"); return 0; }
#include<iostream> using namespace std; class C1 { //默认为私有权限 int m_c1; }; struct C2 { //默认为公共权限 int m_c2; }; int main() { C1 c1; //c1.m_c1; C2 c2; c2.m_c2 = 1000; system("pause"); return 0; }
#include<iostream> using namespace std; class Preson { private: string m_name; int m_age; string m_lover; public: void setName(string name) { m_name = name; } string getName() { return m_name; } void setAge(int age) { if (age < 0 || age > 150) { cout << "你是妖精吧" << endl; } m_age = age; } void setLover(string lover) { m_lover = lover; } string getLover() { return m_lover; } }; int main() { Preson p; p.setName("张三"); cout << "m_name = " << p.getName() << endl; p.setAge(151); p.setLover("波多野结衣"); cout << "m_lover = " << p.getLover() << endl; system("pause"); return 0; }
#include<iostream> using namespace std; #include "point.h" #include "circle.h" //判断点和圆关系的全局函数 void isInCircle(Circle& c, Point& p) { //两点之间距离^2 int ppDistance = (c.getCenter().getX() - p.getX()) * (c.getCenter().getX() - p.getX()) + (c.getCenter().getY() - p.getY()) * (c.getCenter().getY() - p.getY()); //半径^2 int rDistance = c.getR() * c.getR(); //判断 if (ppDistance == rDistance) { cout << "点在圆上" << endl; } else if (ppDistance > rDistance) { cout << "点在圆外" << endl; } else { cout << "点在圆内" << endl; } } int main() { //设置圆,半径为10,圆心坐标为(10,0) Circle c; c.setR(10); Point center; center.setX(10); center.setY(0); c.setCenter(center); //设置点 Point p; p.setX(10); p.setY(11); //判断 isInCircle(c, p); system("pause"); return 0; }
#pragma once #include <iostream> using namespace std; class Point { private: //坐标X int m_x; //坐标Y int m_y; public: //设置X void setX(int x); //获取X int getX(); //设置Y void setY(int y); //获取Y int getY(); };
#include "point.h" //设置X void Point::setX(int x) { m_x = x; } //获取X int Point::getX() { return m_x; } //设置Y void Point::setY(int y) { m_y = y; } //获取Y int Point::getY() { return m_y; }
#pragma once #include <iostream> using namespace std; #include "point.h" class Circle { private: //半径 int m_r; //圆心,类中有类 Point m_center; public: //设置半径 void setR(int r); //获取半径 int getR(); //设置圆心 void setCenter(Point center); //获取圆心 Point getCenter(); };
#include "circle.h" //设置半径 void Circle::setR(int r) { m_r = r; } //获取半径 int Circle::getR() { return m_r; } //设置圆心 void Circle::setCenter(Point center) { m_center = center; } //获取圆心 Point Circle::getCenter() { return m_center; }
#include <iostream> using namespace std; //构造函数:创建对象时为对象成员属性赋值,由编译器自动调用 //析构函数:对象销毁前系统自动调用 //构造函数语法: //没有返回值也不写void //函数名与类名相同 //可以有参数,因此可以发生重载 //程序调用对象时会自动调用构造,无需手动调用且只会调用一次 //析构函数语法: //没有返回值也不写void //函数名与类名相同,前面加~ //不可以有参数,因此不可以发生重载 //对象销毁前会自动调用析构,无需手动调用且只会调用一次 class Preson { public: //构造函数 Preson() { cout << "Preson构造函数调用" << endl; } //析构函数 ~Preson() { cout << "Preson析构函数调用" << endl; } }; void test01() { Preson p; } int main() { test01(); system("pause"); return 0; }
#include <iostream> using namespace std; //按参数分:有参构造,无参构造 //按类型分:普通构造,拷贝构造 //三种调用方式:括号法,显示法,隐式转换法 class Preson { public: int age; public: //无参(默认)构造函数 Preson() { cout << "无参构造函数调用" << endl; } //有参构造函数 Preson(int a) { age = a; cout << "有参构造函数调用" << endl; } //拷贝构造函数 Preson(const Preson& p) { age = p.age; cout << "拷贝构造函数调用" << endl; } //析构函数 ~Preson() { cout << "析构函数调用" << endl; } }; //调用无参构造函数 void test01() { Preson p; } //调用有参构造函数 void test02() { //括号法 Preson p1(10); //Preson p2(); //调用无参构造函数不要这样写,编译器会认为是函数声明 //显示法 Preson p2 = Preson(10); Preson p3 = Preson(p2); //Preson(10) //这是匿名对象,当前行结束之后马上析构 //隐式转换法 Preson p4 = 10; //Preson p4 = Preson(10); Preson p5 = p4; //Preson p5 = Preson(p4); //Preson p5(p4); //不能利用拷贝构造函数初始化匿名对象,编译器会认为是函数声明 } int main() { //test01(); test02(); system("pause"); return 0; }
#include <iostream> using namespace std; //拷贝构造函数调用三种情况: //使用一个已经创建完毕的对象初始化一个新对象 //值传递方式给函数参数传值 //值传递方式返回局部对象 class Preson { public: int age; public: //无参(默认)构造函数 Preson() { age = 0; cout << "无参构造函数调用" << endl; } //有参构造函数 Preson(int a) { age = a; cout << "有参构造函数调用" << endl; } //拷贝构造函数 Preson(const Preson& p) { age = p.age; cout << "拷贝构造函数调用" << endl; } //析构函数 ~Preson() { cout << "析构函数调用" << endl; } }; //使用一个已经创建完毕的对象初始化一个新对象 void test01() { Preson p1(100); Preson p2(p1); Preson p3 = p1; } //值传递方式给函数参数传值 void doWork01(Preson p) { } void test02() { Preson p; doWork01(p); } //值传递方式返回局部对象 Preson doWork02() { Preson p; cout << (int)&p << endl; return p; } void test03() { Preson p = doWork02(); cout << (int)&p << endl; } int main() { //test01(); //test02(); test03(); system("pause"); return 0; }
#include <iostream> using namespace std; //默认情况下,C++编译器至少给一个类添加三个函数 //默认无参构造函数 //默认析构函数 //默认拷贝构造函数 //若用户定义有参构造函数,C++编译器不再提供默认无参构造函数,但会提供默认拷贝构造函数 //若用户定义拷贝构造函数,C++编译器什么也不提供 class Preson { public: int age; public: //无参(默认)构造函数 Preson() { cout << "无参构造函数调用" << endl; } //有参构造函数 Preson(int a) { age = a; cout << "有参构造函数调用" << endl; } //拷贝构造函数 Preson(const Preson& p) { age = p.age; cout << "拷贝构造函数调用" << endl; } //析构函数 ~Preson() { cout << "析构函数调用" << endl; } }; void test01() { Preson p1(100); Preson p2(p1); //若不写拷贝构造函数,C++编译器会自动添加并做浅拷贝操作 cout << "p2年龄 = " << p2.age << endl; } void test02() { Preson p1; Preson p2(10); Preson p3(p2); Preson p4; Preson p5(10); Preson p6(p5); } int main() { //test01(); test02(); system("pause"); return 0; }
#include <iostream> using namespace std; //浅拷贝:简单的赋值拷贝操作 //深拷贝:在堆区重新申请空间进行拷贝操作 class Preson { public: int m_age; int* m_hieght; public: //无参(默认)构造函数 Preson() { cout << "无参构造函数调用" << endl; } //有参构造函数 Preson(int age, int height) { m_age = age; m_hieght = new int(height); cout << "有参构造函数调用" << endl; } //拷贝构造函数 Preson(const Preson& p) { m_age = p.m_age; m_hieght = new int(*p.m_hieght); //如果类属性是在堆区开辟的,一定要自己提供拷贝函数,防止浅拷贝带来的问题 cout << "拷贝构造函数调用" << endl; //如果不利用深拷贝在堆区创建新内存,会导致浅拷贝带来重复释放堆区问题 } //析构函数 ~Preson() { if (m_hieght != NULL) { delete m_hieght; } cout << "析构函数调用" << endl; } }; void test01() { Preson p1(18, 100); Preson p2(p1); cout << "p1年龄 = " << p1.m_age << endl; cout << "p1体重 = " << *p1.m_hieght << endl; cout << "p2年龄 = " << p2.m_age << endl; cout << "p2体重 = " << *p2.m_hieght << endl; } int main() { test01(); system("pause"); return 0; }
#include <iostream> using namespace std; class Preson { private: int m_a; int m_b; int m_c; public: //传统方式 /*Preson(int a, int b, int c) { m_a = a; m_b = b; m_c = c; }*/ Preson(int a, int b, int c) :m_a(a), m_b(b), m_c(c) { } void printPreson() { cout << "mA = " << m_a << endl; cout << "mB = " << m_b << endl; cout << "mC = " << m_c << endl; } }; int main() { Preson p(1, 2, 3); p.printPreson(); system("pause"); return 0; }
#include <iostream> using namespace std; //类1中包含另一个类2时, //构造函数先执行类2在执行类1 //析构函数先执行类1在执行类2 class Phone { public: string m_phoneName; public: Phone(string name) { m_phoneName = name; cout << "Phone构造函数" << endl; } ~Phone() { cout << "Phone析构函数" << endl; } }; class Preson { public: string m_name; Phone m_phoneNmae; public: Preson(string name, string pname) :m_name(name), m_phoneNmae(pname) { cout << "Preson构造函数" << endl; } ~Preson() { cout << "Preson析构函数" << endl; } void playShow() { cout << m_name << " 使用 " << m_phoneNmae.m_phoneName << " 牌子手机" << endl; } }; void test01() { Preson p("张三", "IphoneX"); p.playShow(); } int main() { test01(); system("pause"); return 0; }
#include <iostream> using namespace std; //静态成员变量: //所有对象共享同一份数据 //在编译阶段分配内存 //类内声明类外初始化 class Preson { public: static int m_a; private: static int m_b; }; int Preson::m_a = 100; int Preson::m_b = 1000; void test01() { //通过对象访问 Preson p1; p1.m_a = 100; cout << "p1.m_a " << p1.m_a << endl; //共享同一份数据 Preson p2; p2.m_a = 200; cout << "p1.m_a " << p1.m_a << endl; cout << "p2.m_a " << p2.m_a << endl; //通过类名访问 cout << "m_a " << Preson::m_a << endl; //cout << "m_b " << Preson::m_b << endl; //私有权限访问不到 } int main() { test01(); system("pause"); return 0; }
#include <iostream> using namespace std; //静态成员函数: //所有对象共享同一个函数 //静态成员函数只能访问静态成员变量 class Preson { public: static int m_a; int m_b; public: static void func1() { m_a = 100; //m_b = 100; cout << "func1()调用" << endl; } private: static void func2() { cout << "func2()调用" << endl; } }; int Preson::m_a = 1000; void test01() { //通过对象访问 Preson p1; p1.func1(); //通过类名访问 Preson::func1(); //Preson::func2(); } int main() { test01(); system("pause"); return 0; }
#include <iostream> using namespace std; //在C++中,类的成员变量和成员函数分开存储 //只有非静态成员变量占对象空间 class Preson { public: Preson() { } int m_a; /*static int m_b; void func1() { } static void func2() { }*/ }; int main() { cout << sizeof(Preson) << endl; system("pause"); return 0; }
#include <iostream> using namespace std; //this指针指向被调用成员函数所属的对象 //this指针是隐含在每一个非静态成员函数内的一种指针 //this指针不需要定义,直接使用即可 //this指针用途: //1、当形参和成员变量重名时,可以用this指针来区分 //2、在类的非静态成员函数中返回对象本身,可使用return *this class Preson { public: int age; public: Preson(int age) { //1、 this->age = age; } //2、 Preson& presonAdd(Preson p) { this->age += p.age; return *this; } }; void test01() { Preson p1(10); cout << "p1.age = " << p1.age << endl; Preson p2(10); p2.presonAdd(p1).presonAdd(p1).presonAdd(p1); cout << "p2.age = " << p2.age << endl; } int main() { test01(); system("pause"); return 0; }
#include <iostream> using namespace std; class Preson { public: int m_age; public: void showClassName() { cout << "我是showClassName()" << endl; } void showPreson() { if (this == NULL) { return; } cout << "我是showPreson()" << endl; } }; void test01() { Preson* p = NULL; p->showClassName(); p->showPreson(); } int main() { test01(); system("pause"); return 0; }
#include <iostream> using namespace std; //成员函数后加const称为常函数 //常函数内不可以修改成员属性 //成员属性在声明时加mutable关键字后,在常函数中依然可以修改 //声明对象前加const称为常对象 //常对象只能调用常函数 class Preson { public: int m_a; mutable int m_b; public: Preson() { m_a = 0; m_b = 0; } //this指针本质为一个指针常量,指针指向不可以修改 //如果想指针指向的值也不可以修改,需声明常函数 void func1() const { //this = NULL; //不能修改指针指向 //this->m_a = 100; //不能修改指针指向的值 this->m_b = 100; } }; void test01() { //常对象 const Preson p; //p.m_a = 100; p.m_b = 100; p.func1(); } int main() { test01(); system("pause"); return 0; }
#include <iostream> using namespace std; //全局函数做友元 class Building { friend void goodGay(Building* b); public: string m_SittingRoom; private: string m_BedRoom; public: Building() { this->m_SittingRoom = "客厅"; this->m_BedRoom = "卧室"; } }; void goodGay(Building* b) { cout << "好基友正在访问:" << b->m_SittingRoom << endl; cout << "好基友正在访问:" << b->m_BedRoom << endl; } void test01() { Building b; goodGay(&b); } int main() { test01(); system("pause"); return 0; }
#include <iostream> using namespace std; //类做友元 class Building; class GoodGay { private: Building* b; public: GoodGay(); void visit(); }; class Building { friend class GoodGay; public: string m_SittingRoom; private: string m_BedRoom; public: Building(); }; Building::Building() { this->m_SittingRoom = "客厅"; this->m_BedRoom = "卧室"; } GoodGay::GoodGay() { b = new Building; } void GoodGay::visit() { cout << "好基友正在访问:" << b->m_SittingRoom << endl; cout << "好基友正在访问:" << b->m_BedRoom << endl; } void test01() { GoodGay gg; gg.visit(); } int main() { test01(); system("pause"); return 0; }
#include <iostream> using namespace std; //成员函数做友元 class Building; class GoodGay { private: Building* b; public: GoodGay(); void visit(); void visit2(); }; class Building { friend void GoodGay::visit(); public: string m_SittingRoom; private: string m_BedRoom; public: Building(); }; Building::Building() { this->m_SittingRoom = "客厅"; this->m_BedRoom = "卧室"; } GoodGay::GoodGay() { b = new Building; } void GoodGay::visit() { cout << "好基友正在访问:" << b->m_SittingRoom << endl; cout << "好基友正在访问:" << b->m_BedRoom << endl; } void GoodGay::visit2() { cout << "好基友正在访问:" << b->m_SittingRoom << endl; //cout << "好基友正在访问:" << b->m_BedRoom << endl; } void test01() { GoodGay gg; gg.visit(); gg.visit2(); } int main() { test01(); system("pause"); return 0; }
#include <iostream> using namespace std; //加号运算符重载 //实现两个自定义数据类型相加运算 class Preson { public: int m_a; int m_b; public: Preson() { } Preson(int a, int b) { this->m_a = a; this->m_b = b; } //成员函数实现 /*Preson operator+(Preson& p) { Preson val; val.m_a = this->m_a + p.m_a; val.m_b = this->m_b + p.m_b; return val; }*/ }; //全局函数实现 Preson operator+(Preson& p1, Preson& p2) { Preson val(0, 0); val.m_a = p1.m_a + p2.m_a; val.m_b = p1.m_b + p2.m_b; return val; } //运算符重载的同时也可以发生函数重载 Preson operator+(Preson& p1, int n) { Preson val(0, 0); val.m_a = p1.m_a + n; val.m_b = p1.m_b + n; return val; } void test01() { Preson p1(10, 20); Preson p2(10, 20); Preson p3 = p1 + p2; Preson p4 = p3 + 10; cout << "m_a = " << p3.m_a << endl; cout << "m_b = " << p3.m_b << endl; cout << "m_a = " << p4.m_a << endl; cout << "m_b = " << p4.m_b << endl; } int main() { test01(); system("pause"); return 0; }
#include <iostream> using namespace std; //左移运算符重载 //可以输出自定义数据类型 class Preson { friend ostream& operator<<(ostream& cout, Preson& p); private: int m_a; int m_b; public: Preson(int a, int b) { this->m_a = a; this->m_b = b; } //成员函数实现不了 //p << cout 不是我们想要的格式 }; //全局函数实现 ostream& operator<<(ostream& out, Preson& p) { out << "m_a = " << p.m_a << endl; out << "m_b = " << p.m_b << endl; return out; } void test01() { Preson p(10, 100); cout << p << endl; //链式编程 } int main() { test01(); system("pause"); return 0; }
#include <iostream> using namespace std; //递增运算符重载 class myInt { friend ostream& operator<<(ostream& out, myInt mi); private: int m_num; public: myInt() { m_num = 10; } //前置++ myInt& operator++() { //先++在return m_num++; return *this; } //后置++ myInt operator++(int) { //先return在++ myInt mi = *this; m_num++; return mi; } }; ostream& operator<<(ostream& out, myInt mi) { out << mi.m_num; return out; } //前置++ void test01() { myInt mi; cout << ++mi << endl; cout << mi << endl; } //后置++ void test02() { myInt mi; cout << mi++ << endl; cout << mi << endl; } int main() { test01(); test02(); system("pause"); return 0; }
#include <iostream> using namespace std; //赋值运算符重载 class Preson { public: int* m_age; public: Preson(int age) { m_age = new int(age); } Preson& operator=(Preson& p) { if (m_age != NULL) { delete m_age; m_age = NULL; } //编译器提供的是浅拷贝 //m_age = p.m_age; //深拷贝 m_age = new int(*p.m_age); return *this; } ~Preson() { if (m_age != NULL) { delete m_age; m_age = NULL; } } }; void test01() { Preson p1(10); Preson p2(20); Preson p3(30); p3 = p2 = p1; 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; system("pause"); return 0; }
#include <iostream> using namespace std; //关系运算符重载 class Preson { public: string m_name; int m_age; public: Preson(string name, int age) { this->m_name = name; this->m_age = age; } bool operator==(Preson& p) { if (this->m_name == p.m_name && this->m_age == p.m_age) { return true; } else { return false; } } bool operator!=(Preson& p) { if (this->m_name == p.m_name && this->m_age == p.m_age) { return false; } else { return true; } } }; void test01() { Preson p1("张三", 20); Preson p2("张三", 22); if (p1 == p2) { cout << "p1==p2" << endl; } else { cout << "p1!=p2" << endl; } if (p1 != p2) { cout << "p1!=p2" << endl; } else { cout << "p1==p2" << endl; } } int main() { test01(); system("pause"); return 0; }
#include <iostream> using namespace std; //函数调用运算符重载 //也称为仿函数(),没有固定写法,非常灵活 class myPrint { public: void operator()(string s) { cout << s << endl; } }; void test01() { myPrint mp; mp("hello world"); } class myAdd { public: int operator()(int a, int b) { return a + b; } }; void test02() { myAdd ma; int n = ma(10, 20); cout << "n = " << n << endl; //匿名对象调用 cout << "myAdd()(1000, 1000) = " << myAdd()(1000, 1000) << endl; } int main() { test01(); test02(); system("pause"); return 0; }
#include <iostream> using namespace std; //继承:减少重复代码 //子类,父类 //派生类,基类 class basePage { public: void header() { cout << "公共头部" << endl; } void footer() { cout << "公共底部" << endl; } }; class Java :public basePage { public: void concent() { cout << "Java学习视频" << endl; } }; class Python :public basePage { public: void concent() { cout << "Python学习视频" << endl; } }; class CPP :public basePage { public: void concent() { cout << "CPP学习视频" << endl; } }; void test01() { Java ja; ja.header(); ja.footer(); ja.concent(); Python py; py.header(); py.footer(); py.concent(); CPP cp; cp.header(); cp.footer(); cp.concent(); } int main() { test01(); system("pause"); return 0; }
#include <iostream> using namespace std; //公有继承 class Base1 { public: int m_a; protected: int m_b; private: int m_c; }; class Son1 :public Base1 { void func() { m_a; //可访问,public权限 m_b; //可访问,protected权限 //m_c; //不可访问 } }; void test01() { Son1 s1; s1.m_a; } //保护继承 class Base2 { public: int m_a; protected: int m_b; private: int m_c; }; class Son2 :protected Base2 { void func() { m_a; //可访问,protected权限 m_b; //可访问,protected权限 //m_c; //不可访问 } }; void test02() { Son2 s2; } //私有继承 class Base3 { public: int m_a; protected: int m_b; private: int m_c; }; class Son3 :private Base3 { void func() { m_a; //可访问,private权限 m_b; //可访问,private权限 //m_c; //不可访问 } }; void test03() { Son3 s3; } int main() { test01(); test02(); test03(); system("pause"); return 0; }
#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; }; void test01() { cout << sizeof(Son) << endl; //16 } int main() { test01(); system("pause"); return 0; }
#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; } }; void test01() { Son s; } int main() { test01(); system("pause"); return 0; }
#include <iostream> using namespace std; //子类对象可以直接访问子类同名成员 //子类对象加作用域可以访问父类同名成员 //子类和父类有同名成员函数时,子类会隐藏父类同名成员函数,若想访问需加作用域 class Base { public: int m_a; public: Base() { m_a = 100; } void func() { cout << "Base func()调用" << endl; } void func(int a) { cout << "Base func(int a)调用" << endl; } }; class Son :public Base { public: int m_a; public: Son() { m_a = 200; } void func() { cout << "Son func()调用" << endl; } }; void test01() { Son s; cout << "Son的m_a = " << s.m_a << endl; cout << "Base的m_a = " << s.Base::m_a << endl; s.func(); s.Base::func(); s.Base::func(10); } int main() { test01(); system("pause"); return 0; }
#include <iostream> using namespace std; class Base { public: static int m_a; public: static void func() { cout << "Base func()调用" << endl; } static void func(int a) { cout << "Base func(int a)调用" << endl; } }; int Base::m_a = 100; class Son :public Base { public: static int m_a; public: static void func() { cout << "Son func()调用" << endl; } }; int Son::m_a = 200; //同名成员属性 void test01() { //通过对象访问 Son s; cout << "Son的m_a = " << s.m_a << endl; cout << "Base的m_a = " << s.Base::m_a << endl; //通过类名访问 cout << "Son的m_a = " << Son::m_a << endl; cout << "Base的m_a = " << Son::Base::m_a << endl; } //同名成员函数 void test02() { //通过对象访问 Son s; s.func(); s.Base::func(); //通过类名访问 Son::func(); //Base::代表作用域 Son::Base::func(); Son::Base::func(100); } int main() { test01(); test02(); system("pause"); return 0; }
#include <iostream> using namespace std; class Base1 { public: int m_a; public: Base1() { m_a = 100; } }; class Base2 { public: int m_a; public: Base2() { m_a = 200; } }; class Son :public Base1, public Base2 { public: int m_c; int m_d; public: Son() { m_c = 300; m_d = 400; } }; void test01() { Son s; cout << sizeof(Son) << endl; cout << s.Base1::m_a << endl; cout << s.Base2::m_a << endl; } int main() { test01(); system("pause"); return 0; }
#include <iostream> using namespace std; //菱形继承带来的主要问题是子类继承两份相同的数据,导致资源浪费且毫无意义 //利用虚继承解决菱形继承问题 class Animal { public: int m_age; }; class Yang :virtual public Animal { }; class Tuo :virtual public Animal { }; class YangTuo :public Yang, public Tuo { }; void test01() { YangTuo yt; yt.Yang::m_age = 100; yt.Tuo::m_age = 200; cout << "yt.Yang::m_age = " << yt.Yang::m_age << endl; cout << "yt.Tuo::m_age = " << yt.Tuo::m_age << endl; cout << "yt.m_age = " << yt.m_age << endl; } int main() { test01(); system("pause"); return 0; }
#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; } }; void doSpeak(Animal& a) { a.speak(); } void test01() { Cat cat; doSpeak(cat); Dog dog; doSpeak(dog); } int main() { test01(); system("pause"); return 0; }
#include <iostream> using namespace std; class jiSuanQi { public: int m_num1; int m_num2; public: virtual int getResult() { return 0; } }; class jiajiSuanQi :public jiSuanQi { public: int getResult() { return m_num1 + m_num2; } }; class jianjiSuanQi :public jiSuanQi { public: int getResult() { return m_num1 - m_num2; } }; class chengjiSuanQi :public jiSuanQi { public: int getResult() { return m_num1 * m_num2; } }; class chujiSuanQi :public jiSuanQi { public: int getResult() { return m_num1 / m_num2; } }; void test01() { //加法 jiSuanQi* jsq = new jiajiSuanQi; jsq->m_num1 = 200; jsq->m_num2 = 100; cout << "加法 = " << jsq->getResult() << endl; delete jsq; //减法 jsq = new jianjiSuanQi; jsq->m_num1 = 200; jsq->m_num2 = 100; cout << "减法 = " << jsq->getResult() << endl; delete jsq; //乘法 jsq = new chengjiSuanQi; jsq->m_num1 = 200; jsq->m_num2 = 100; cout << "乘法 = " << jsq->getResult() << endl; delete jsq; //除法 jsq = new chujiSuanQi; jsq->m_num1 = 200; jsq->m_num2 = 100; cout << "除法 = " << jsq->getResult() << endl; delete jsq; } int main() { test01(); system("pause"); return 0; }
#include <iostream> using namespace std; //在多态中,通常父类中的虚函数是毫无意义的,主要都是调用子类中重写的内容 //因此可以将虚函数改为纯虚函数 //当类中有了纯虚函数,这个类也称为抽象类 //抽象类特点: //无法实例化对象 //子类必须重写抽象类中的纯虚函数,否则也属于抽象类 class Base { public: //纯虚函数 virtual void func() = 0; }; class Son :public Base { public: void func() { cout << "func()调用" << endl; } }; void test01() { Base* base = NULL; //base = new Base; base = new Son; base->func(); delete base; } int main() { test01(); system("pause"); return 0; }
#include <iostream> using namespace std; class zhiZuoYinPin { public: virtual void shaoShui() = 0; virtual void chongPao() = 0; virtual void heTa() = 0; void liuCheng() { shaoShui(); chongPao(); heTa(); } }; class Coffee :public zhiZuoYinPin { void shaoShui() { cout << "加热农夫山泉" << endl; } void chongPao() { cout << "冲泡咖啡" << endl; } void heTa() { cout << "喝咖啡" << endl; } }; class Tea :public zhiZuoYinPin { void shaoShui() { cout << "加热百岁山" << endl; } void chongPao() { cout << "冲泡龙井" << endl; } void heTa() { cout << "喝龙井" << endl; } }; void doWork(zhiZuoYinPin* zzyp) { zzyp->liuCheng(); delete zzyp; } void test01() { doWork(new Coffee); doWork(new Tea); } int main() { test01(); system("pause"); return 0; }
#include <iostream> using namespace std; //使用多态时,如果子类中有属性开辟到堆区,那么父类指针在释放时无法调用到子类的析构函数 //解决办法:将父类中的析构函数改为虚析构或纯虚析构 //虚析构和纯虚析构 //共性: //可以解决父类指针释放子类对象 //都需要有具体的函数实现 //区别: //如果是纯虚析构函数,该类属于抽象类,无法实例化 //如果子类中没有堆区数据,可以不写虚析构或纯虚析构 class Animal { public: virtual void speak() = 0; Animal() { cout << "Animal()构造函数调用" << endl; } //虚析构函数 /*virtual ~Animal() { cout << "Animal()虚析构函数调用" << endl; }*/ //纯虚析构函数 virtual ~Animal() = 0; }; Animal::~Animal() { cout << "Animal()纯虚析构函数调用" << endl; } class Cat :public Animal { public: string* m_name; public: Cat(string name) { cout << "Cat构造函数调用" << endl; m_name = new string(name); } virtual ~Cat() { cout << "Cat析构函数调用" << endl; if (this->m_name != NULL) { delete m_name; m_name = NULL; } } void speak() { cout << *m_name << "小猫在说话" << endl; } }; void test01() { Animal* a = new Cat("Tom"); a->speak(); //通过父类指针去释放,会导致子类对象清理不干净,造成内存泄露 delete a; //给父类增加一个虚析构函数或纯虚析构函数 } int main() { test01(); system("pause"); return 0; }
#include <iostream> using namespace std; //C++中对文件操作需包含头文件<fstream> #include <fstream> //文件类型分为两种: //文本文件,以ASCII码形式存储 //二进制文件,以二进制形式存储 //操作文件的三大类: //ofstream,写操作 //ifstream,读操作 //fstream,写读操作 //文本文件,写文件步骤: //包含头文件 //创建流对象 //打开文件 //写数据 //关闭文件 //文件打开方式: //ios::in 为读文件而打开文件 //ios::out 为写文件而打开文件 //ios::ate 初始位置:文件尾 //ios::app 追加方式写文件 //ios::trunc 如果文件存在先删除,在创建 //ios::binary 二进制方式 //文件打开方式可以配合 | 操作符使用 //如二进制方式写文件 ios::binary | ios::out void test01() { ofstream ofs; ofs.open("test.txt", ios::out); ofs << "姓名 = 张三" << endl; ofs << "性别 = 男" << endl; ofs.close(); } int main() { test01(); system("pause"); return 0; }
#include <iostream> using namespace std; #include <fstream> //文本文件读文件步骤: //包含头文件 //创建流对象 //打开文件并判断文件是否打开成功 //读数据 //关闭文件 void test01() { ifstream ifs; ifs.open("test.txt", ios::in); if (!ifs.is_open()) { cout << "文件打开失败" << endl; return; } //1 /*char buff[1024] = { 0 }; while (ifs >> buff) { cout << buff << endl; }*/ //2 /*char buff[1024] = { 0 }; while (ifs.getline(buff, sizeof(buff))) { cout << buff << endl; }*/ //3 char c; while ((c = ifs.get()) != EOF) { cout << c; } ifs.close(); } int main() { test01(); system("pause"); return 0; }
#include <iostream> using namespace std; #include <fstream> //ostream& write(char* buffer , int len) //buffer指向内存中一段存储空间,len是读写字节数 class Preson { public: char m_name[64]; int m_age; }; void test01() { ofstream ofs("Preson.txt", ios::out | ios::binary); Preson p{ "李四",18 }; ofs.write((const char*)&p, sizeof(p)); ofs.close(); } int main() { test01(); system("pause"); return 0; }
#include <iostream> using namespace std; #include <fstream> //istream& read(char* buffer , int len) //buffer指向内存中一段存储空间,len是读写字节数 class Preson { public: char m_name[64]; int m_age; }; void test01() { ifstream ifs("Preson.txt", ios::in | ios::binary); if (!ifs.is_open()) { cout << "文件打开失败" << endl; return; } Preson p; ifs.read((char*)&p, sizeof(p)); cout << "姓名 = " << p.m_name << endl; cout << "年龄 = " << p.m_age << endl; } int main() { test01(); system("pause"); return 0; }
end