【C++】纯虚函数和抽象类
一、纯虚函数(1)语法virtual 返回类型 函数名(形参列表) = 0; (2)虚函数表12345678910class Base{private: int val;public: Base(int x = 0): val(x){} ~Base(){} virtual void fun() = 0; virtual void show()const {cout << val << endl;}}; 二、抽象类概念:只要含有一个纯虚函数,该类就叫做抽象类 抽象类不能实例化对象,由抽象类继承而来的派生类,必须重写基类中的纯虚函数,否则该派生类也无法实例化对象(也是抽象类) 三、接口类1234567struct Interface{ //接口一 virtual void fun1() = 0; //接口二 virtual void fun2() = 0;};
【C++】free delete delete[]注意事项
一、尽量配套使用 申请 释放 malloc free new() delete new[] delete[] 二、原因我们举例说明: 12345678class Test{private: int num;public: Test(int x = 0): num(x){} ~Test(){}}; (1)申请一个Test()Test* tp = new Test();内存模型结论: 可以使用delete tp; 可以free(tp),但是不适用自定义类型(未调用析构函数) 不可以delete[],将上越界标记识别成对象个数,导致崩溃 (2)申请一组Test[10]Test* array = new Test[10]; 内存模型:结论: 不可以free,将对象个数当作上越界标记,导致崩溃 不可以delete,将对象个数当作上越界标记,导致崩溃 可以delete[],正确识别对象个数,正确识别上越界标记
【C++】C语言实现继承和多态
一、C语言实现继承原理:结构体组合类123456789101112131415161718192021222324252627282930//基类typedef struct Base{ //基类自身属性和方法 int b_val = 0; void show() { printf("b_val:%d\n", b_val); }}Base;typedef struct Son{ //隐藏基类对象 Base base; //派生类自身属性和函数 int s_val = 10; void show() { printf("s_val:%d\n", s_val); }}Son;int main(){ Son s; s.show(); s.base.show(); return 0;} 二、C语言实现多态(1)静态多态原理:使用宏实现静态多态:函数重载、运算符重载 123456789#define SUM(A,B) (A)+(B)int main( ...
【C++】虚表指针和虚函数表
一、虚表指针和虚函数表定义 虚表指针:指向虚函数表首地址的一个指针,存在于每个基类对象的内存中,在调用构造函数构造对象时,设置虚表指针__vfptr 虚函数表:在编译阶段生成,编译器将类中虚函数的地址存放在虚函数表中,虚函数表存在于全局数据区.data,每个类仅有一个,供所有对象共享。 二、虚函数表生成我们已经清楚虚函数表是在编译期间生成的,那我们详细看看虚函数表的生成过程吧,以下面代码为例 1234567891011121314151617181920class A{private: int val;public: A(int x = 0): val(x){ cout << "A()" << endl; } virtual ~A(){ cout << "~A()" << endl; } virtual void fun1(){ cout << "A::fun1()" << endl; ...
【C++】虚函数与多态
一、虚函数类成员方法(除过构造函数)前使用virtual关键字,将函数声明成虚函数。类外实现函数的定义无需在前加virtual关键字。 12345678class Person{public: virtual void work() { cout << "工作" << endl; }};二、多态静态多态:编译期间就已经确定函数的调用时机(函数重载、运算符重载)动态多态:运行时确定函数的调用时机 动态多态触发条件: 公有继承中 基类含有虚函数&&派生类重写虚函数 使用基类指针或引用访问派生类成员方法 1234567891011121314151617181920212223242526272829303132333435363738class Person{public: virtual void work() { cout << "工作" << endl; }};class Student : ...
【C++】继承中对象构造与析构、赋值
一、构造/析构顺序及继承性1234567891011121314151617181920212223242526272829class A{private: int _a;public: A(int a = 0): _a(a) { cout << "A()" << this << endl; } ~A() { cout << "~A()"<< this <<endl; }};class B : public A{private: int _b;public: B(int b): _b(b), A() { cout << "B()" << this << endl; } ~B() { cout << "~B()"<< this <<endl; } ...
【C++】继承中的同名隐藏和赋值兼容规则
一、继承中同名隐藏(1)同名成员属性1234567891011121314151617class A{public: int _a;};class B : public A{public: int _a; //这个_apublic: void fun() { _a = 10; //就近原则 A::_a = 20; //加上作用域访问 }}; (2)同名成员方法123456789101112131415161718class A{public: void fun(){ cout << "A::fun" << endl;}};class B : public A{public: void fun(){ cout << "B::fun" << endl;}};int main(){ B b; b.fun(); b.A::fun(); return ...
【C++】继承中的权限
一、默认权限struct 默认公有权限1234struct A{public:};class 默认私有权限 1234class B{private:}; 二、默认继承权限(1)class 继承 struct12struct A{};class B : A{}; //默认私有继承 (2)struct 继承 class12class A{};struct B : A{}; //默认公有继承 😀总结:以派生类的默认权限作为继承权限 三、继承权限探究(1)公有继承12345678910111213141516171819class Base{private: int _Ba;protected: int _Bb;public: int _Bc;};class Son : public Base{private: int _Sa;protected: int _Sb;public: int _Sc;}; 😋Son的内存结构模型( ...
【C++】STL中list仿写
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022 ...
【leetcode 203】移除链表元素
(一)题目描述 (二)题目意图删除head链表中所有的val == Node.val的结点,最终返回头结点。 (三)题目分析 head结点和非头结点的删除方式不同 是否使用伪头结点 我的错误分析:误以为head中的val不作为val==head->val的条件,所以未对head结点进行处理。未考虑到的:head结点为nullptr (四)画图分析例如:删除[6,2,6,3,4,5,6]中的6 (1)未使用伪头结点 可以看到删除的结点既有头结点、中间结点、尾结点。代码: 1234567891011121314151617181920212223242526272829303132//不使用伪头结点class Solution {public: ListNode* removeElements(ListNode* head, int val){ //删除头结点 //头结点不为nullptr head->val == val while(head != NULL && head->val == ...