析构函数
构造函数在创建一个对象实例的时候运行;
析构函数在销毁一个对象的时候运行。
析构函数通常用在需要设置变量或者初始化工作的时候;
释放任何内容或者清理内存空间的时候;
栈和堆分配的内存;
用new关键字创建一个对象(存在于堆上),然后调用delete,析构函数就会被调用;
基于栈的对象,这个对象被删除,析构函数也会被调用。
#include <iostream>
class Entity
{
public:
float X, Y; //用来表示Entity的位置
Entity() //Entity的构造函数,不用再调用e.Init()函数
{
X = 0.0f;
Y = 0.0f;
std::cout << "Created Entity" << std::endl;
}
Entity(float x, float y)
{
X = x;
Y = y;
}
~Entity()
{
std::cout << "Destroyed Entity" << std::endl;
}
void Print()
{
std::cout << X << "," << Y << std::endl;
}
};
void Function()
{
Entity e;
e.Print();
}
int main()
{
Function();
std::cin.get();
}
继承(Inheritance)
继承使类之间有了相互关联的层级关系(有一个包含通用功能的积累)
最开始的父类中可以创建出很多派生类
帮助避免写很多重复代码(或者代码略微不同但实际上是在做同样的事)
继承:把一系列的所有通用diamante放到基类中
创建了一个子类,会包含父类的一切
std::cout << sizeof(Entity) << std::endl; //8
std::cout << sizeof(Player) << std::endl; //12
#include <iostream>
class Entity
{
public:
float X, Y; //8字节
void Move(float xa, float ya)
{
X += xa;
Y += ya;
}
};
class Player :public Entity //继承了Entity的所有功能
{
public:
const char* Name; //4字节
void PrintName()
{
std::cout << Name << std::endl;
}
};
int main()
{
Player player;
player.Move(5, 5);
player.X = 2;
std::cin.get();
}
多态——使用单一的符号来表示多个不同的类型
虚函数(virtual funations)
虚函数可以在子类中重写方法
比如有两个类A,B,B是A的子类
在A类里新建一个方法并把它标记为虚函数,也可在B类中重写这个方法去做其他事。
#include <iostream>
#include <string>
class Entity
{
public:
std::string GetName() { return "Entity"; }
};
class Player :public Entity
{
private:
std::string m_Name;
public:
Player(const std::string& name)
:m_Name(name) {}
std::string GetName() { return m_Name; }
};
int main()
{
Entity* e = new Entity(); //创建一个Entity,打印Entity的GetName返回值
std::cout << e->GetName() << std::endl;
Player* p = new Player("Cherno"); //程序终止,对象被自动删除,不用手动删除
std::cout << p->GetName() << std::endl;
std::cin.get();
}
#include <iostream>
#include <string>
class Entity
{
public:
virtual std::string GetName() { return "Entity"; } //如果想重写一个函数,必须要把基类中的原函数设置为虚函数。
};
class Player :public Entity
{
private:
std::string m_Name;
public:
Player(const std::string& name)
:m_Name(name) {}
std::string GetName() override { return m_Name; } //c++新标准允许给被重写的函数用"override"关键词标记
};
void PrintName(Entity* entity)
{
std::cout << entity->GetName() << std::endl;
}
int main()
{
Entity* e = new Entity(); //创建一个Entity,打印Entity的GetName返回值
PrintName(e);
Player* p = new Player("Cherno"); //程序终止,对象被自动删除,不用手动删除
PrintName(p);
std::cin.get();
}
override——代码可读性更好;预防bug(比如拼写错误)
虚函数运行时的性能花费:
需要额外的内存用来存储虚表。这样可以分配到正确的函数,基类里还有一个指针成员指向虚表。
每次调用虚函数,必须遍历虚表找到最重要运行的程序。