C++中的接口有什么用

2023年12月13日,周三上午

今天上午在适配器模式,我发现如果想真正理解适配器模式,就必须学会使用C++中的接口,就必须明白为什么要在C++中使用接口,所以重新学习了一下C++中的接口


目录


C++中的接口有什么用

在C++中,虽然没有像其他编程语言(如Java和C#)中的明确接口(interface)概念,但可以使用抽象类来实现类似的功能。

接口在软件开发中起到了以下几个重要的作用:

  • 实现多态性:接口提供了一种定义规范的方式,可以通过多态性实现对象的替换和统一的调用方式。通过接口,不同的类可以实现相同的接口,并以统一的方式进行调用。

  • 隐藏实现细节:接口定义了一组可供外部使用的方法,同时隐藏了具体实现的细节。这样,使用接口的代码只需要关注接口定义的方法,而不需要了解具体的实现细节。

  • 实现代码解耦:通过接口,将不同的部分分离开来,使得代码的耦合度降低。接口作为一个中间层,将不同的模块解耦,使得代码更加灵活和可维护。

  • 提高代码的可扩展性:通过接口,可以为系统提供一种扩展的方式。当需要增加新的功能时,只需要实现相应的接口并符合接口定义的规范,而无需修改原有的代码。

用代码说明"实现多态性"

cpp 复制代码
#include <iostream>

// 定义接口(抽象类)
class Shape {
public:
	virtual void draw() = 0; // 纯虚函数
};

// 实现接口的类
class Circle : public Shape {
public:
	void draw() override {
		std::cout << "Drawing a circle." << std::endl;
	}
};

class Rectangle : public Shape {
public:
	void draw() override {
		std::cout << "Drawing a rectangle." << std::endl;
	}
};

int main() {
	// 创建接口指针,并使用多态性调用不同的实现类的方法
	Shape* shape1 = new Circle();
	Shape* shape2 = new Rectangle();
	
	shape1->draw(); // 调用Circle类的draw方法
	shape2->draw(); // 调用Rectangle类的draw方法
	
	delete shape1;
	delete shape2;
	
	return 0;
}

在这个例子中,定义了一个接口Shape,其中包含纯虚函数draw()。

然后,创建了两个实现了该接口的类Circle和Rectangle,并分别实现了draw()方法。

在main()函数中,创建了两个接口指针shape1和shape2,分别指向Circle和Rectangle的对象。通过这两个指针,可以以统一的方式调用不同的实现类的方法,实现了多态性。

用代码说明"隐藏实现细节"

cpp 复制代码
#include <iostream>

// 定义接口(抽象类)
class Database {
public:
	virtual void connect() = 0; // 纯虚函数
	virtual void query(const std::string& sql) = 0; // 纯虚函数
};

// 实现接口的类
class MySQLDatabase : public Database {
public:
	void connect() override {
		std::cout << "Connected to MySQL database." << std::endl;
	}
	
	void query(const std::string& sql) override {
		std::cout << "Executing query: " << sql << std::endl;
		// 实际的查询逻辑
	}
};

int main() {
	// 使用接口指针调用接口的方法,隐藏了具体实现的细节
	Database* db = new MySQLDatabase();
	db->connect();
	db->query("SELECT * FROM customers");
	
	delete db;
	
	return 0;
}

在这个例子中,定义了一个接口Database,其中包含纯虚函数connect()和query()。

然后,创建了一个实现了该接口的类MySQLDatabase,并实现了这两个方法。

在main()函数中,通过接口指针db调用接口的方法,而不需要关心具体实现的细节。这样,可以隐藏实现的细节,只需要使用接口提供的方法即可。

为了更好的说明"通过接口隐藏实现细节",现在我来假设一个场景:

我是一个主程序员,然后还下辖了另一个程序员。

现在我发现程序需要对数据库进行操作,然后我就用抽象类了定义一个数据库操作类,在这个数据库操作类里面用虚函数写了很多我认为程序会使用到的函数。

之后,我把实现这个抽象类------数据库操作类的任务交给了我下辖的程序员。

我下辖的程序员实现后,我只需要通过这个抽象类或者说接口通过指针或引用直接调用我下辖的程序员实现的功能就可以了,我不需要知道他是怎么实现的。

用代码说明"实现代码解耦"

cpp 复制代码
#include <iostream>

// 定义接口(抽象类)
class Logger {
public:
	virtual void log(const std::string& message) = 0; // 纯虚函数
};

// 实现接口的类
class ConsoleLogger : public Logger {
public:
	void log(const std::string& message) override {
		std::cout << "Console Logger: " << message << std::endl;
	}
};

class FileLogger : public Logger {
public:
	void log(const std::string& message) override {
		std::cout << "File Logger: " << message << std::endl;
		// 将日志写入文件
	}
};

class LogManager {
private:
	Logger* logger;
	
public:
	LogManager(Logger* logger) {
		this->logger = logger;
	}
	
	void doLog(const std::string& message) {
		logger->log(message);
	}
};

int main() 
{
	// 创建不同的日志记录器对象,并将其注入到日志管理器中
	Logger* consoleLogger = new ConsoleLogger();
	Logger* fileLogger = new FileLogger();
	
	LogManager logManager1(consoleLogger);
	LogManager logManager2(fileLogger);
	
	// 调用日志管理器的方法,实现了代码的解耦 
	logManager1.doLog("This is a log message from console logger."); 
	logManager2.doLog("This is a log message from file logger.");
	
	delete consoleLogger; 
	delete fileLogger;
	
	return 0; 
}

在这个例子中,定义了一个接口Logger,其中包含纯虚函数log()。

然后,创建了两个实现了该接口的类ConsoleLogger和FileLogger,并分别实现了log()方法。

接下来,创建了一个LogManager类,其中包含一个Logger指针成员变量。在LogManager的构造函数中,将不同的日志记录器对象注入到LogManager中。

在main()函数中,创建了两个LogManager对象logManager1和logManager2,分别使用了ConsoleLogger和FileLogger作为日志记录器。通过调用LogManager的方法,实现了代码的解耦,不同的日志记录器对象可以被注入到LogManager中,实现了灵活的日志记录功能。

相关推荐
Yue丶越16 分钟前
【C语言】自定义类型:结构体
c语言·开发语言
辞旧 lekkk17 分钟前
【c++】封装红黑树实现mymap和myset
c++·学习·算法·萌新
合作小小程序员小小店18 分钟前
桌面开发,点餐管理系统开发,基于C#,winform,sql server数据库
开发语言·数据库·sql·microsoft·c#
笃行客从不躺平22 分钟前
线程池监控是什么
java·开发语言
星轨初途23 分钟前
C++的输入输出(上)(算法竞赛类)
开发语言·c++·经验分享·笔记·算法
极地星光35 分钟前
Qt/C++ 单例模式深度解析:饿汉式与懒汉式实战指南
c++·qt·单例模式
yuuki2332331 小时前
【C++】类和对象(上)
c++·后端·算法
再睡一夏就好1 小时前
string.h头文件中strcpy、memset等常见函数的使用介绍与模拟实现
c语言·c++·笔记·string·内存函数·strcpy
dangdang___go1 小时前
动态内存管理||malloc和free.realloc和calloc
c语言·开发语言·算法·动态内存管理
YA3331 小时前
mcp-grafana mcp 使用stdio报错
java·开发语言