C++虚函数
C++类中用virtual修饰的函数 称之为虚函数
- 虚函数对类的影响:让对象的内存增加4个字节(32操作系统)
- 虚函数表:存放所有的虚函数
#include<iostream>
using namespace std;
class YXC {
public:
// 虚函数
virtual void print() {
cout << "我是虚函数" << endl;
}
virtual void print2() {
cout << "我也是虚函数" << endl;
}
};
int main() {
cout << sizeof(YXC) << endl;
// 虚函数指针
YXC yxc;
long** p = (long**)& yxc;
using pFunc = void(*)();
pFunc pf = (pFunc)p[0][0];
pf();
pFunc pf2 = (pFunc)p[0][1];
pf2();
return 0;
}
C++虚函数和多态
多态指是同一行为的不同结果,大人,小孩坐车,一个免费一个需要收费
静态联编:函数重载
动态联编:C++类的多态
多态实现的前提条件
- 父类必须存在和子类一致的函数,并且是虚函数
- public继承才有多态
- 必须存在指针引用
// 概念不重要,重要的是你要知道什么情况,该调用什么函数
#include<iostream>
#include<string>
using namespace std;
class YXC {
public:
virtual void print() {
cout << "父类虚函数" << endl;
}
void printData() {
cout << "父类普通函数" << endl;
}
};
class XC : public YXC {
public:
void print() {
cout << "子类的print函数" << endl;
}
void printData() {
cout << "子类的printData函数" << endl;
}
private:
};
class A {
public:
virtual void print() {
cout << "A" << endl;
}
};
class B :public A {
public:
void print() {
cout << "B" << endl;
}
};
class C :public B {
public:
void print() {
cout << "C" << endl;
}
};
int main() {
// 1.正常对象 --->就近
YXC yxc;
XC xc;
yxc.printData();
yxc.print();
xc.printData();
xc.print();
// 2.正常的指针 --->就近
YXC* pYXC = new YXC;
XC* pXc = new XC;
pYXC->print();
pYXC->printData();
pXc->print();
pXc->printData();
// 3.不正常的赋值
// 允许操作: 父类指针被子类的对象
// 用多态的最终目的:用父类指针调用子类方法
pYXC = new XC;
pYXC->print(); // 有virtual 看对象
pYXC->printData(); // 无virtual 看指针类型
pYXC = new YXC; // new
pYXC->print(); // 多态
pYXC = &xc;
pYXC->print(); // 存在
YXC& pRight = xc; // 引用也算--->知道就行,千万别用
pRight.print();
// 虚函数被多层继承
B* pB = new C;
pB->print();
A* pA = new C; // 隔代了
pA->print();
pA->A::print();
return 0;
}
C++纯虚函数和ADT
- 纯虚函数是没有函数体的虚函数,纯虚函数也是虚函数
- virtual 函数返回值类型 函数名(参数)=0;
- 具有纯虚函数的类叫做抽象
- 抽象类没有办法构建对象
- 抽象类可以构建对象指针
#include<iostream>
#include<string>
using namespace std;
class YXC {
public:
YXC(string name,int age):name(name),age(age){}
virtual void print() = 0;
protected:
string name;
int age;
};
class XC : public YXC {
public:
XC() :YXC("易小川",18){}
// 重写概念:
void print() {
cout << "XC重写print" << endl;
}
protected:
};
// ADT : 抽象数据类型
//
class StuSystem {
public:
virtual void insertData() = 0;
virtual void deleteData() = 0;
virtual void showData() const = 0;
virtual int size() const = 0;
virtual int empty() const = 0;
protected:
};
class listSystem :public StuSystem {
public:
void insertData(){}
void deleteData(){}
void showData() const{}
int size() const { return 0; }
int empty() const { return 0; }
protected:
};
void testData() {
StuSystem* ps = new listSystem;
ps->insertData();
ps->insertData();
ps->showData();
}
int main() {
// YXC xc; // 抽象类不能构建对象
YXC* pYXC = nullptr;
pYXC = new XC;
pYXC->print();
testData();
return 0;
}
C++虚析构函数
析构函数用virtual 修饰就是虚析构函数
存在子类指针被子类对象初始化的情况,通常大家要写虚析构函数
#include<iostream>
#include<string>
using namespace std;
class YXC {
public:
~YXC() // 父类用虚析构函数
{
cout << "MM" << endl;
}
};
class XC :public YXC {
public:
~XC() {
cout << "XC" << endl;
}
};
int main() {
{
YXC* pYxc = new XC;
delete pYxc;
}
return 0;
}
C++内联思想
当前函数编译后 二进制的形式存在,以牺牲空间的方式提高效率,内联函数的特点,一定是短小精悍
- C++中用inline修饰的函数
- 类中实现的函数默认为内联
#include<iostream>
using namespace std;
inline int Max(int a, int b) {
return a > b ? a : b;
}
class YXC {
public:
void print() {
cout << "默认为内联函数" << endl;
}
inline void printData();
};
void YXC::printData() {
cout << "类外实现" << endl;
}
int main() {
YXC yxc;
yxc.print();
yxc.printData();
return 0;
}
C++结构体
C++类中能干的事情,结构体可以干
- 构造函数
- 继承
- 多态
- 重写
- 重载
C++结构体默认属性是public,类中默认属性是private属性
// 业余选手可以这样搞,专业选手不这样做,因为低耦合,高内聚的追求
#include<iostream>
#include<string>
using namespace std;
struct YXC {
string name;
int age;
void print() {
cout << name << "\t" << age << endl;
}
};
struct XC {
string name;
int age;
XC(string name,int age):name(name),age(age){}
void print() {
cout << this->name << "\t" << this->age << endl;
}
};
struct YXG {
protected:
string name;
int age;
public:
YXG(string name, int age) :name(name), age(age) {}
public:
void print() {
cout << this->name << "\t" << this->age << endl;
}
};
struct XG : public YXG {
XG() :YXG("YXG",16){}
~XG() {
cout << "析构函数" << endl;
}
};
int main() {
YXC yxc = { "name",18 }; // 没有写构造函数,跟C语言语法一模一样的
yxc.print();
XC xc = { "name",18 }; // 一旦写了构造函数 , 当类使用
cout << xc.name << "\t" << xc.age << endl;
YXG yxg("YXG", 20);
yxg.print();
XG xg;
xg.print();
return 0;
}