摘要:
难点 1.不注意普通函数加上template<> 就成了模板函数, 而友元函数声明的时普通函数, 找不到普通函数的实现链接 err1 2.类内声明了模板函数,但此时声明因为有 <>所以编译器看不到,需要在这之前先声明函数 3.声明了函数还是会报错,因为函数中的参数 Person类并没有声明,所以还要
阅读全文
posted @ 2021-08-24 17:57
BZ易风
阅读(77)
推荐(0)
编辑
摘要:
友元函数类内实现 friend void printPerson( Person<T1 ,T2> & p ) 友元函数类外实现 friend void printPerson<>(Person<T1, T2> & p); //没有<>普通函数 声明 加上 <>模板函数声明 让编译器看到 函数 并且看
阅读全文
posted @ 2021-08-24 17:43
BZ易风
阅读(68)
推荐(0)
编辑
摘要:
分文件解决 .h .cpp分别写声明和实现 但是由于 类模板的成员函数运行阶段才去创建,导致包含.h头文件,不会创建函数的实现,无法解析外部命令 解决方案 保护 .cpp文件 (不推荐) 不要进行分文件编写,写到同一个文件中,进行声明和实现,后缀名改为.hpp 约定俗成的 (.hpp文件即分文件模板
阅读全文
posted @ 2021-08-24 17:24
BZ易风
阅读(246)
推荐(0)
编辑
摘要:
1. template <class T1, class T2> Person<T1, T2>::Person(T1 name, T2 age) #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> using n
阅读全文
posted @ 2021-08-24 17:08
BZ易风
阅读(128)
推荐(0)
编辑
摘要:
基类如果是模板类,必须让子类告诉编译器 基类中的T到底是什么类型 如果不告诉,那么无法分配内存,编译不过 利用参数列表class Child :public Base<int> #define _CRT_SECURE_NO_WARNINGS #include <iostream> using nam
阅读全文
posted @ 2021-08-24 16:59
BZ易风
阅读(36)
推荐(0)
编辑
摘要:
1. typeid(T).name(); //可以查看泛型传入的时什么类型数据
阅读全文
posted @ 2021-08-24 16:37
BZ易风
阅读(84)
推荐(0)
编辑
摘要:
三种方式 显示指定类型 参数模板化 整体模板化 实例: #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> using namespace std; //类模板 template<class NameT, cla
阅读全文
posted @ 2021-08-24 16:35
BZ易风
阅读(45)
推荐(0)
编辑
摘要:
类模板 语法:template <T…> 紧跟着是类 区别: 与函数模板区别,可以有默认类型参数 函数模板可以进行自动类型推导,而类模板不可以 类模板中的成员函数 一开始不会创建出来,而是在运行时才去创建 #define _CRT_SECURE_NO_WARNINGS #include <iostr
阅读全文
posted @ 2021-08-24 15:59
BZ易风
阅读(178)
推荐(0)
编辑
摘要:
1. #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> using namespace std; class Person { public: Person(string name, int age) { th
阅读全文
posted @ 2021-08-24 15:48
BZ易风
阅读(43)
推荐(0)
编辑
摘要:
函数模板机制结论: 编译器并不是把函数模板处理成能够处理任何类型的函数,模板不是万能的,不能通用所有的数据类型 函数模板通过具体类型产生不同的函数,模板并不能直接调用,生成后的模板函数才可以调用 编译器会对函数模板进行两次编译,在声明的地方对模板代码本身进行编译,在调用的地方对参数替换后的代码进行编
阅读全文
posted @ 2021-08-24 15:32
BZ易风
阅读(51)
推荐(0)
编辑
摘要:
区别 普通函数可以进行隐式类型转换 模板不可以 #define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; //1.普通函数和函数模板的区别 template<class T> T myPlus(T a, T b)
阅读全文
posted @ 2021-08-24 15:09
BZ易风
阅读(92)
推荐(0)
编辑
摘要:
函数模板 template < class / typename T> 告诉编译器紧跟的代码里出现T不要报错 mySwap( T &a T &b ) 类型也需要传入 ,类型参数化 myswap(a,b) 自动类型推导 按照a b的类型 来替换T myswap<int>(a,b) 显示指定类型 实例:
阅读全文
posted @ 2021-08-24 14:39
BZ易风
阅读(57)
推荐(0)
编辑
摘要:
1. 基类转派生类 向下类型转换 不安全的 派生类转 基类 向上类型转换 安全 如果发生多态 总是安全的 父类中如果写了虚函数,而子类没有任何重写,有意义吗? 没有意义
阅读全文
posted @ 2021-08-24 11:27
BZ易风
阅读(126)
推荐(0)
编辑
摘要:
虚析构 virtual ~类名() {} 解决问题: 通过父类指针指向子类对象释放时候不干净导致的问题 纯虚析构函数 写法 virtual ~类名() = 0 类内声明 类外实现 如果出现了纯虚析构函数,这个类也算抽象类,不可以实例化对象 不用虚析构的化,delete子类的时候,只会调用父类的析构
阅读全文
posted @ 2021-08-24 11:18
BZ易风
阅读(71)
推荐(0)
编辑
摘要:
纯虚函数 仅想对基类进行向上类型转换,使用它的接口,而不希望用户实际的创建一个基类的对象 抽象类 在基类中加入至少一个纯虚函数(pure virtual function),使得基类称为抽象类(abstract class). 纯虚函数使用关键字virtual,并在其后面加上=0。如果试图去实例化一
阅读全文
posted @ 2021-08-24 10:52
BZ易风
阅读(86)
推荐(0)
编辑
摘要:
解析 当父类中有了虚函数后,内部结构就发生了改变 内部多了一个 vfprt virtual function pointer 虚函数表指针 指向 vftable 虚函数表 父类中结构 vfptr &Animal::speak 子类中 进行继承 会继承 vfptr vftable 构造函数中 会将虚函
阅读全文
posted @ 2021-08-24 09:35
BZ易风
阅读(52)
推荐(0)
编辑
摘要:
多态的成立条件 有继承 子类重写父类虚函数函数 返回值,函数名字,函数参数,必须和父类完全一致(析构函数除外) 子类中virtual关键字可写可不写,建议写 类型兼容,父类指针,父类引用 指向 子类对象 多态分类 静态多态 函数重载 动态多态 虚函数 继承关系 c++支持编译时多态(静态多态)和运行
阅读全文
posted @ 2021-08-23 21:59
BZ易风
阅读(257)
推荐(0)
编辑
摘要:
1。对照表来看 代码: #define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; class Animal { public: int m_Age; }; //虚基类 Sheep class Sheep:virt
阅读全文
posted @ 2021-08-23 20:40
BZ易风
阅读(202)
推荐(0)
编辑
摘要:
菱形继承解决方案 利用虚继承 操作的时共享的一份数据 sheepTuo内部结构 vbptr 虚基类指针 v:virtual b:base p:pointer 指向一张 虚基类表 通过表找到偏移量 找到共有的数据 如图:类Sheep和Tuo保留的只是虚函数指针,只有Animal里才有数据 实例: #d
阅读全文
posted @ 2021-08-23 17:59
BZ易风
阅读(78)
推荐(0)
编辑
摘要:
两个派生类继承同一个基类而又有某个类同时继承者两个派生类,这种继承被称为菱形继承,或者钻石型继承。 这种继承所带来的问题: 羊继承了动物的数据和函数,鸵同样继承了动物的数据和函数,当草泥马调用函数或者数据时,就会产生二义性。 草泥马继承自动物的函数和数据继承了两份,其实我们应该清楚,这份数据我们只需
阅读全文
posted @ 2021-08-23 17:42
BZ易风
阅读(103)
推荐(0)
编辑
摘要:
同时继承多个基类 class A : public B1, public B2,…. 引发二义性问题 想解决二义性问题,就需要通过作用域来进行区分 #define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; cla
阅读全文
posted @ 2021-08-23 17:38
BZ易风
阅读(39)
推荐(0)
编辑
摘要:
1.构造函数 2.析构函数 3.operator=
阅读全文
posted @ 2021-08-23 17:28
BZ易风
阅读(22)
推荐(0)
编辑
摘要:
类似非静态成员函数处理 如果想访问父类中的成员,加作用域即可 1.子类可以继承静态成员属性 如果有重名静态成员,就近原则 静态成员方法 #define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; class Bas
阅读全文
posted @ 2021-08-23 17:21
BZ易风
阅读(80)
推荐(0)
编辑
摘要:
处理方法 当子类成员和父类成员同名时,子类依然从父类继承同名成员 如果子类有成员和父类同名,子类访问其成员默认访问子类的成员(本作用域,就近原则) 在子类通过作用域::进行同名成员区分(在派生类中使用基类的同名成员,显示使用类名限定符) 成员属性 直接调用先调用子类,如果想调用父类 需要作用域 成员
阅读全文
posted @ 2021-08-23 17:02
BZ易风
阅读(163)
推荐(0)
编辑
摘要:
调用原则: 子类对象在创建时会首先调用父类的构造函数 父类构造函数执行完毕后,才会调用子类的构造函数 当父类构造函数有参数时,需要在子类初始化列表(参数列表)中显示调用父类构造函数 析构函数调用顺序和构造函数相反 1.顺序 1.1 子类创建对象时,先调用父类的构造,然后调用自身构造 1.2 析构顺序
阅读全文
posted @ 2021-08-23 16:32
BZ易风
阅读(94)
推荐(0)
编辑
摘要:
1.打开vs2019开发人员命令提示 进入问价夹,dir查看文件在不在 然后输入固定语法: cl /d1 报告单个类的布局[跟类名] 属于哪个cpp文件 cl /d1 reportSingleClassLayoutSon test.cpp 可以看到
阅读全文
posted @ 2021-08-23 16:23
BZ易风
阅读(121)
推荐(0)
编辑
摘要:
1.子类中 会继承父类的私有成员,只是被编译器隐藏起来了,无法访问父类的私有成员,但是sizeof会给私有成员空间 子类会继承父类中所有的内容 ,包括了 私有属性 只是我们访问不到,编译器给隐藏了 cl /d1 reportSingleClassLayout类名 文件名 #define _CRT_S
阅读全文
posted @ 2021-08-23 16:12
BZ易风
阅读(26)
推荐(0)
编辑
摘要:
public:公有继承 protected:保护继承 private:私有继承 关系: 不管公有继承 保护 还是私有 基类中的私有属性 ,都不可以继承下去 公有继承 父类中的protected 在子类中是 protected 父类中的public 在子类中是 public 保护继承 父类中的prot
阅读全文
posted @ 2021-08-23 15:40
BZ易风
阅读(30)
推荐(0)
编辑
摘要:
减少代码的重复 #define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; class BasePage { public: void Header() { cout << "公共头部" << endl; } };
阅读全文
posted @ 2021-08-23 15:30
BZ易风
阅读(24)
推荐(0)
编辑
摘要:
1. 优先级 运算符 名称或含义 使用形式 结合方向 说明 1 [] 数组下标 数组名[常量表达式] 左到右 -- () 圆括号 (表达式)/函数名(形参表) -- . 成员选择(对象) 对象.成员名 -- -> 成员选择(指针) 对象指针->成员名 -- 2 - 负号运算符 -表达式 右到左 单目
阅读全文
posted @ 2021-08-23 15:17
BZ易风
阅读(114)
推荐(0)
编辑
摘要:
l =, [], () 和 -> 操作符只能通过成员函数进行重载 l << 和 >>只能通过全局函数配合友元函数进行重载 l 不要重载 && 和 || 操作符,因为无法实现短路规则
阅读全文
posted @ 2021-08-23 15:11
BZ易风
阅读(49)
推荐(0)
编辑
摘要:
用法一: #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> using namespace std; class myPrint { public: //()重载 void operator()(string
阅读全文
posted @ 2021-08-23 15:01
BZ易风
阅读(74)
推荐(0)
编辑
摘要:
1. int strcmp(const char *s1, const char *s2); 功能:比较 s1 和 s2 的大小,比较的是不相同的第一个字符ASCII码大小。 参数: s1:字符串1首地址 s2:字符串2首地址 返回值: 相等:0 大于:>0 小于:<0 实例: #define _C
阅读全文
posted @ 2021-08-23 14:52
BZ易风
阅读(165)
推荐(0)
编辑
摘要:
1.1 返回数组索引的引用 1.2 int & operator[](int index) 1.3 return this->pAddress[index] int& operator[](int index) { return this->p_Address[index]; }
阅读全文
posted @ 2021-08-23 14:36
BZ易风
阅读(48)
推荐(0)
编辑
摘要:
一个类默认创建时 默认构造、析构、拷贝构造和operator=赋值运算符重载(浅拷贝) 进行简单的值传递 1.1 系统默认给类提供 赋值运算符写法 是简单值拷贝 1.2 导致如果类中有指向堆区的指针,就可能出现深浅拷贝的问题 #define _CRT_SECURE_NO_WARNINGS #incl
阅读全文
posted @ 2021-08-23 13:48
BZ易风
阅读(69)
推荐(0)
编辑
摘要:
智能指针的实现 Person类有showAge 成员函数 如果new出来的Person对象,就要让程序员自觉的去释放 delete 有了智能指针,让智能指针托管这个Person对象,对象的释放就不用操心了,让智能指针管理 为了让智能指针想普通的Person*指针一样使用 就要重载 -> 和* #de
阅读全文
posted @ 2021-08-23 11:19
BZ易风
阅读(161)
推荐(0)
编辑
摘要:
前置和后置自增 自己实现int类型 MyInteger 内部维护以int数据 MyInteger myInt myInt ++ 后置 ++myInt 前置 重载++运算符 operator++() 前置 operator++(int) 后置 前置理念 先++ 后返回自身 后置理念 先保存住原有值 内
阅读全文
posted @ 2021-08-23 10:14
BZ易风
阅读(120)
推荐(0)
编辑
摘要:
不要随意乱用符号重载 内置数据类型 的运算符不可以重载 cout << 直接对Person自定义数据类型 进行输出 写到全局函数中 ostream& operator<< ( ostream & cout, Person & p1 ) {} #define _CRT_SECURE_NO_WARNIN
阅读全文
posted @ 2021-08-22 13:23
BZ易风
阅读(49)
推荐(0)
编辑
摘要:
加号运算符重载 如果想让自定义数据类型 进行+运算,那么就需要重载 + 运算符 在成员函数 或者 全局函数里 重写一个+运算符的函数 函数名 operator+ () {} 运算符重载 也可以提供多个版本 #define _CRT_SECURE_NO_WARNINGS #include <iostr
阅读全文
posted @ 2021-08-22 11:53
BZ易风
阅读(29)
推荐(0)
编辑
摘要:
成员函数做友元函数 #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> using namespace std; //只让Visit可以作为友元函数 Visit2不可以 class House; //先声明,防止
阅读全文
posted @ 2021-08-21 23:22
BZ易风
阅读(120)
推荐(0)
编辑