C/C++ 关于继承与多态笔记

继承的基本语法: 继承的目的就是用于提高代码的可用性,减少代码的重复内容,高效开发。

#include <iostream>

using namespace std;

class BasePage
{
private:
	int m_x;

protected:
	int m_y;

public:
	void header() { cout << "header" << endl; }
	void footer() { cout << "footer" << endl; }
};

// 新建一个News类,以公有属性继承BasePage类中的内容
class News :public BasePage
{
public:
	void connect() { cout << "connect" << endl; }
};

int main(int argc, char *argv[])
{
	News news;
	news.header();
	news.footer();

	system("pause");
	return 0;
}

继承中的构造/析构函数:

#include <iostream>

using namespace std;

class BasePage
{
public:
	BasePage(){ cout << "base page -> start" << endl; }
	~BasePage(){ cout << "base page -> end" << endl; }
};

class News :public BasePage
{
public:
	News(){ cout << "news page -> start" << endl; }
	~News(){ cout << "news page -> end" << endl; }
};

void call()
{  // 此处如果初始化写在main中,将无法看到析构函数的执行
	News news;
}

int main(int argc, char *argv[])
{
	call();
	system("pause");
	return 0;
}

继承下的同名函数调用:

#include <iostream>

using namespace std;

class BasePage
{
public:
	void func(int x, int y)
	{
		cout << "BasePage -> " << x + y << endl;
	}
};

class News :public BasePage
{
public:
	void func(int x, int y)
	{
		cout << "News -> " << x + y << endl;
	}
};

int main(int argc, char *argv[])
{
	News news;
	
	// 如果想调用父类的func()则需要
	news.BasePage::func(10,20);

	// 调用子类的则是
	news.func(100, 200);

	system("pause");
	return 0;
}

继承下的静态成员属性:

#include <iostream>

using namespace std;

class BasePage
{
public:
	static int m_x;

public:
	static void func(int x, int y) {cout << "BasePage -> " << x + y << endl;}
};

class News :public BasePage
{
public:
	static int m_x;

public:
	static void func(int x, int y) {cout << "News -> " << x + y << endl;}
};

int BasePage::m_x = 100;
int News::m_x = 200;

int main(int argc, char *argv[])
{
	News news;

	cout << News::m_x << endl;
	cout << News::BasePage::m_x << endl;

	News::func(10,20);
	News::BasePage::func(100,200);

	system("pause");
	return 0;
}

多继承的调用:

#include <iostream>

using namespace std;

class Base1
{
public:
	int m_x;
public:
	Base1(){ m_x = 10; }
	void show() { cout << m_x << endl; }
};

class Base2
{
public:
	int m_x;
public:
	Base2(){ m_x = 20; }
	void show() { cout << m_x << endl; }
};

class Super :public Base1, public Base2
{
public:
	int m_y;
public:
	Super(){ m_y = 30; }
	void display(){ cout << m_y << endl; }
};

int main(int argc, char *argv[])
{
	Super super;

	cout << super.Base1::m_x << endl;
	cout << super.Base2::m_x << endl;
	cout << super.m_y << endl;

	super.Base1::show();
	super.display();

	system("pause");
	return 0;
}

菱形继承(虚继承): 盖继承,可能会出现多个基类中存在相同的成员数据,这样会造成,内存开销。虚基类即可实现解决共享的开销问题。

#include <iostream>

using namespace std;

class Animal
{
public:
	int m_Age;
};

// 虚基类 Sheep
class Sheep :virtual public Animal { };

// 虚基类 Tuo
class Tuo :virtual public Animal { };

// 定义派生类
class SheepTuo :public Sheep, public Tuo { };

int main(int argc, char *argv[])
{
	SheepTuo ptr;

	ptr.Sheep::m_Age = 10;
	ptr.Tuo::m_Age = 20;

	cout << ptr.Sheep::m_Age << endl;
	cout << ptr.Tuo::m_Age << endl;
	cout << ptr.m_Age << endl;

	system("pause");
	return 0;
}

虚函数实现动态多态: 动态多态,实现了,根据传递的指针不同,调用同一个接口,返回不同的结果。

#include<iostream>

using namespace std;

class Animal
{
public:
	virtual void speak() { cout << "Animal speak" << endl; }
	virtual void eat() { cout << "Animal eat" << endl; }
};

class Cat :public Animal
{
public:
	void speak() { cout << "Cat speak" << endl; }
	virtual void eat() { cout << "cat eat" << endl; }
};

class Dog :public Animal
{
public:
	void speak() { cout << "Dog speak" << endl; }
	virtual void eat() { cout << "dog eat" << endl; }
};

void doSpeak(Animal & animal)
{
	animal.speak();
}

int main(int argc, char *argv[])
{
	Cat cat_ptr;
	doSpeak(cat_ptr);    // 调用同一个函数,返回不同的结果

	Dog dog_ptr;
	doSpeak(dog_ptr);

	system("pause");
	return EXIT_SUCCESS;
}

纯虚函数实现多态: 如果父类中有了纯虚函数,子类继承父类就必须要实现纯虚函数。父类中存在纯虚函数,该类无法实例化对象,只能被继承后实现,这种类被叫做抽象类。多态设计原则,开闭原则。

#include <iostream>

using namespace std;

class AbstractCalculator
{
public:
	int x;
	int y;

public:
	// virtual int getResult() { return 0; };    // 定义虚函数
	virtual int getResult() = 0;                 // 定义纯虚函数
	void Set_Val(int x, int y){ this->x = x; this->y = y; };
};

class AddCalculator :public AbstractCalculator
{
public:
	virtual int getResult()   // 扩展getResult方法
	{
		return x + y;
	}
};

class SubCalculator :public AbstractCalculator
{
public:
	virtual int getResult()
	{
		return x - y;
	}
};

int main(int argc, char *argv[])
{
	AbstractCalculator *ptr = new AddCalculator;   // 创建一个加法
	ptr->Set_Val(10, 20);
	cout << "x+y = " << ptr->getResult() << endl;
	delete ptr;

	ptr = new SubCalculator;   // 创建一个减法
	ptr->Set_Val(10, 20);
	cout << "x-y = " << ptr->getResult() << endl;
	delete ptr;

	system("pause");
	return 0;
}

实现虚析构: 在基类的析构函数上加上virtual修饰为虚析构函数,这样就能让派生类的元素进行释放了。

解决父类指针,释放子类对象是,释放不干净的问题。

普通析构 是不会调用子类的析构的,所以可能会导致释放不干净,利用虚析构来解决这个问题

#include <iostream>

using namespace std;

class Animal
{
public:
	// 此处加上virtual声明为虚析构函数
	virtual ~Animal() { cout << "Animal back" << endl; }
};

class Cat :public Animal
{
public:
	char *m_name;

public:
	Cat(const char *name)
	{
		this->m_name = new char[strlen(name) + 1];
		strcpy(this->m_name, name);
	}
	~Cat()
	{
		cout << "Cat back" << endl;
		if (this->m_name != NULL)
		{
			delete[] this->m_name;
			this->m_name = NULL;
		}
	}
};

int main(int argc, char *argv[])
{
	Animal *ptr = new Cat("Tomcat");
	delete ptr;
	system("pause");
	return 0;
}

实现纯虚析构: 纯虚析构函数,必须要存在实现,实现必须在类外进行实现,因为类内无法实现。

如果函数中出现了 纯虚析构函数,那么这个类也算抽象类,抽象类 不可实例化对象

#include <iostream>

using namespace std;

class Animal
{
public:
	// 此处加上 virtual 声明为纯虚析构函数
	virtual ~Animal() = 0 ;
};

Animal::~Animal()
{
	// 纯虚析构函数实现
	cout << "Animal back" << endl;
}

class Cat :public Animal
{
public:
	char *m_name;

public:
	Cat(const char *name)
	{
		this->m_name = new char[strlen(name) + 1];
		strcpy(this->m_name, name);
	}
	~Cat()
	{
		cout << "Cat back" << endl;
		if (this->m_name != NULL)
		{
			delete[] this->m_name;
			this->m_name = NULL;
		}
	}
};

int main(int argc, char *argv[])
{
	Animal *ptr = new Cat("Tomcat");
	delete ptr;
	system("pause");
	return 0;
}
posted @   lyshark  阅读(287)  评论(0编辑  收藏  举报
(评论功能已被禁用)
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
历史上的今天:
2019-05-12 Amoeba 实现MySQL读写分离

8952084 | 6896846
博客园 - 开发者的网上家园

点击右上角即可分享
微信分享提示