C++设计模式 --1.工厂模式和单例模式

文章目录

  • 1.工厂模式
    • 简单工厂模式
    • 工厂方法模式
    • 抽象工厂模式
  • 2.单例模式
    • 懒汉式
    • 饿汉式

1.工厂模式

简单工厂模式

抽象产品类

//定义一个抽象水果类 --抽象产品角色
class AbstractFruit
{
public:
	virtual void showFruitName()=0;//抽取出产品的公共行为, 纯虚函数
    virtual ~AbstractFruit(){};//虚析构函数  -- 做为顶层基类,一定要显示定义虚析构函数,防止内存溢出
};

具体产品类

//苹果类 -- 具体产品角色
class Apple : public AbstractFruit
{
public:
	virtual void showFruitName() override {
		cout << "this is an apple" <<endl;
	}
};

//鸭梨类 -- 具体产品角色
class Pear : public AbstractFruit
{
public:
	virtual void showFruitName() override {
		cout << "this is a pear" <<endl;
	}
};

//香蕉类 -- 具体产品角色
class Banana : public AbstractFruit
{
public:
	virtual void showFruitName() override {
		cout << "create bananas" <<endl;
	}
};

工厂

//工厂类 --工厂角色
/*
	1.内含一个生成具体产品对象的静态方法,根据传入的参数判断要生成的哪种产品,并返回对象指针
	2.通过抽象产品类类型指针来接收具体产品的堆内存地址,达到多态目的。
*/
class FruitFactory
{
public:
	static AbstractFruit* makeFruit(string fruitType){
		if(fruitType == "apple"){
			return new Apple;
		}else if(fruitType == "pear") {
			return new Pear;
		}else if(fruitType == "banana") {
			return new Banana;
		}else {
			return nullptr;
		}
	}
};

客户端

//客户端
/*
  1.通过工厂类调用其创建产品的静态方法,并根据传入的参数 生成具体的产品对象
*/
int main(int argc, char *argv[])
{
	AbstractFruit* fruit = FruitFactory::makeFruit("apple");
	if(fruit != nullptr)
		fruit->showFruitName();
	delete fruit;
	cout << "==============" <<endl;
	fruit = FruitFactory::makeFruit("banana");
	if (fruit != nullptr)
		fruit->showFruitName();
	delete fruit;
	return 0;
}

在这里插入图片描述
简单工厂模式不属于 GoF的23种设计模式。
简单工厂模式 有以下三种角色:
抽象产品角色:简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。
具体产品角色:简单工厂模式所创建的具体实例对象。
工厂角色:简单工厂模式的核心,它负责创建所有实例的内部逻辑,工厂类可以被外界直接调用,创建所需的产品对象。

优点
1.实现客户端和具体实现类解耦;不需要关注对象的创建细节;
2.通过客户端 传入参数 让工厂知道应该创建什么类型对象。
缺点
1.当每增加新类型的具体产品时,需要修改工厂类的中if…else 源代码,不符合开闭原则。
2.这个类过重(很多if…else,及负责生成所有产品),将各种产品对象的初始化集中在一个类中实现,违反了 单一职责原则;
3.并且这个类发生问题,会影响很多使用这个工厂的模块。

简单工厂模式 UML类图:
在这里插入图片描述

工厂方法模式

工厂方法模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统不修改具体工厂角色的情况下引进新的产品。

工厂方法模式是 简单工厂模式 + 开闭原则 +单一职责原则。
工厂方法模式有以下四个角色:
1.抽象工厂角色:工厂方法模式的核心,负责定义公共接口,任何具体工厂类都必须实现这个接口。
2.具体工厂角色:具体工厂是抽象工厂的一个实现,负责实例化产品对象。
3.抽象产品角色:工厂方法模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。
4.具体产品角色:工厂方法模式所创建的具体实例对象。
工厂方法模式的优点:

  1. 符合开闭原则,即抽象工厂中的公共接口是闭的,针对新种类产品,可以通过增加具体工厂来生产,这个是开的,实现可扩展。
  2. 符合单一职责原则,即每个具体工厂只负责生产某一种类的产品。而不像简单工厂模式中在 工厂类中负责生成所有种类产品。
    工厂方法模式的缺点:
  3. 类的成本个数增加,导致类越来越多,增加维护成本。

代码案例:
抽象工厂

//抽象水果工厂
class AbstractFruitFactory
{
public:
	virtual AbstractFruit* makeFruit() = 0;//生产水果的纯虚函数(也叫接口)
	virtual ~AbstractFruitFactory(){};
};

具体工厂

//负责具体生产苹果的苹果工厂
class AppleFactory : public AbstractFruitFactory
{
public:
	AbstractFruit* makeFruit() //实现接口
	{
		return new Apple;
	}
};
//负责具体生产鸭梨的鸭梨工厂
class PearFactory : public AbstractFruitFactory
{
public:
	AbstractFruit* makeFruit() //实现接口
	{
		return new Pear;
	}
};

//负责具体生产香蕉的香蕉工厂
class BananaFactory : public AbstractFruitFactory
{
public:
	AbstractFruit* makeFruit() //实现接口
	{
		return new Banana;
	}
};

抽象产品

//抽象产品
class AbstractFruit
{
public:
	virtual void showFruitName()=0;
    virtual ~AbstractFruit(){};
};

具体产品

//苹果类
class Apple : public AbstractFruit
{
public:
	void showFruitName()
	{
		cout << "this is an apple" << endl;
	}
};
//鸭梨类
class Pear : public AbstractFruit
{
public:
	void showFruitName()
	{
		cout << "this is a pear" << endl;
	}
};
//香蕉类
class Banana : public AbstractFruit
{
public:
	void showFruitName()
	{
		cout << "this is a banana" << endl;
	}
};

客户端调用:

//客户端 --调用
int main(int argc, char *argv[])
{	
	//创建一个抽象工厂类型指针变量
	AbstractFruitFactory* abstractFruitFactory = nullptr;
	//创建一个抽象产品类型指针变量
	AbstractFruit* abstractFruit = nullptr;
	
	//创建生产具体某种产品的工厂类(苹果类),让抽象工厂类型指针指向具体工厂类的对象,从而实现多态
	abstractFruitFactory = new AppleFactory;
	abstractFruit = abstractFruitFactory->makeFruit();

	abstractFruit->showFruitName();

	delete abstractFruitFactory;
	delete abstractFruit;

	cout << "=====================" << endl;
	
	//创建生产具体某种产品的工厂类(鸭梨类),让抽象工厂类型指针指向具体工厂类的对象,从而实现多态
	abstractFruitFactory = new PearFactory;
	abstractFruit = abstractFruitFactory->makeFruit();

	abstractFruit->showFruitName();
	
	delete abstractFruitFactory;
	delete abstractFruit;

	cout << "=====================" << endl;

	//创建生产具体某种产品的工厂类(香蕉类),让抽象工厂类型指针指向具体工厂类的对象,从而实现多态
	abstractFruitFactory = new BananaFactory;
	abstractFruit = abstractFruitFactory->makeFruit();

	abstractFruit->showFruitName();

	delete abstractFruitFactory;
	delete abstractFruit;
	
	return 0;
}

在这里插入图片描述
工厂方法模式UML类图:
在这里插入图片描述

抽象工厂模式

抽象工厂针对的是产品族,而不是产品等级结构。
在这里插入图片描述
抽象工厂模式和工厂方法模式一样也有以下四个角色:
1.抽象工厂角色:抽象工厂模式的核心,负责定义公共接口,任何具体工厂类都必须实现这个接口。
2.具体工厂角色:具体工厂是抽象工厂的一个实现,负责实例化同一产品族的对象。
3.抽象产品角色:抽象工厂模式所创建的相同产品等级对象的父类,它负责描述所有相同产品等级实例所共有的公共接口。
4.具体产品角色:抽象工厂模式所创建的具体实例对象。

可以说 抽象工厂模式是工厂方法模式的升级版。抽象工厂模式指针的是产品族符合开闭原则,而工厂方法模式针对的是多个系列产品符合开闭原则。

代码演示实例:
抽象产品

//抽象苹果类
class AbstractApple
{
public:
	virtual void showName() = 0;
	virtual ~AbstractApple(){};
};

//抽象鸭梨类
class AbstractPear
{
public:
	virtual void showName() = 0;
	virtual ~AbstractPear() {};
};

//抽象香蕉类
class AbstractBanana
{
public:
	virtual void showName() = 0;
	virtual ~AbstractBanana() {};
};

具体产品`:

//中国苹果
class ChinaApple : public AbstractApple
{
public:
	void showName()
	{
		cout << "this is a ChinaApple" << endl;	
	}
};

//中国鸭梨
class ChinaPear : public AbstractPear
{
public:
	void showName()
	{
		cout << "this is a ChinaPear" << endl;
	}
};

//中国香蕉
class ChinaBanana : public AbstractBanana
{
public:
	void showName()
	{
		cout << "this is a ChinaBanana" << endl;
	}
};


//美国苹果
class AmericaApple : public AbstractApple
{
public:
	void showName()
	{
		cout << "this is an AmericaApple" << endl;
	}
};


//美国鸭梨
class AmericaPear : public AbstractPear
{
public:
	void showName()
	{
		cout << "this is an AmericaPear" << endl;	
	}
};

//美国香蕉
class AmericaBanana : public AbstractBanana
{
public:
	void showName()
	{
		cout << "this is an AmericaBanana" << endl;
	}
};

//日本苹果
class JapanApple : public AbstractApple
{
public:
	void showName()
	{
		cout << "this is a JapanApple" << endl;
	}
};

//日本鸭梨
class JapanPear : public AbstractPear
{
public:
	void showName()
	{
		cout << "this is a JapanPear" << endl;
	}
};

//日本香蕉
class JapanBanana : public AbstractBanana
{
public:
	void showName()
	{
		cout << "this is a JapanBanana" << endl;
	}
};

抽象工厂:

//抽象工厂类
class AbstractFruitFactory
{
public:
	virtual AbstractApple * createApple() = 0;
	virtual AbstractPear * createPear() = 0;
	virtual AbstractBanana * createBanana() = 0;
	virtual ~AbstractFruitFactory(){};
};

具体工厂:

//中国工厂
class ChinaFruitFactory : public AbstractFruitFactory
{
public:
	AbstractApple * createApple()
	{
		return new ChinaApple;
	};

	AbstractPear * createPear()
	{
		return new ChinaPear;
	};

	AbstractBanana* createBanana()
	{
		return new ChinaBanana;
	};
};

//美国工厂
class AmericaFruitFactory  : public AbstractFruitFactory
{
public:
	AbstractApple * createApple()
	{
		return new AmericaApple;
	};

	AbstractPear * createPear()
	{
		return new AmericaPear;
	};

	AbstractBanana* createBanana()
	{
		return new AmericaBanana;
	};
};

//日本工厂
class JapanFruitFactory : public AbstractFruitFactory
{
public:
	AbstractApple* createApple()
	{
		return new JapanApple;
	};

	AbstractPear* createPear()
	{
		return new JapanPear;
	};

	AbstractBanana* createBanana()
	{
		return new JapanBanana;
	};
};

封装的测试函数:

void testAbstractFactory() {
	AbstractFruitFactory* abstractFruitFactory = nullptr;
	AbstractApple* apple = nullptr;
	AbstractPear* pear = nullptr;
	AbstractBanana* banana = nullptr;

	abstractFruitFactory = new ChinaFruitFactory;
	apple = abstractFruitFactory->createApple();
	apple->showName();
	pear = abstractFruitFactory->createPear();
	pear->showName();
	banana = abstractFruitFactory->createBanana();
	banana->showName();

	delete abstractFruitFactory;
	delete apple;
	delete pear;

	cout << "=======================" << endl;

	abstractFruitFactory = new AmericaFruitFactory;
	apple = abstractFruitFactory->createApple();
	apple->showName();
	pear = abstractFruitFactory->createPear();
	pear->showName();
	banana = abstractFruitFactory->createBanana();
	banana->showName();

	delete abstractFruitFactory;
	delete apple;
	delete pear;

	cout << "=======================" << endl;

	abstractFruitFactory = new JapanFruitFactory;
	apple = abstractFruitFactory->createApple();
	apple->showName();
	pear = abstractFruitFactory->createPear();
	pear->showName();
	banana = abstractFruitFactory->createBanana();
	banana->showName();

	delete abstractFruitFactory;
	delete apple;
	delete pear;
}

客户端--调用

int main(int argc, char *argv[])
{
	testAbstractFactory();
	return 0;
}

在这里插入图片描述
抽象工厂模式UML类图:
在这里插入图片描述

2.单例模式

懒汉式

代码示例如下:

LazySingleton类

//懒汉式
#include <iostream>
using namespace std;

class LazySingleton
{
private:
	LazySingleton(){cout << "LazySingleton constructor" << endl;};//私有化构造函数
	~LazySingleton(){};//私有化析构函数
public:
	static LazySingleton* getSingleton()
	{
		if(singleton == nullptr)
		{
			cout << "生成单例对象" << endl;
			singleton = new LazySingleton;
		}
		return singleton;
	}

private:
	static LazySingleton* singleton;//声明
};

//定义静态成员变量
LazySingleton*  LazySingleton::singleton = nullptr; //在main函数执行前会进行静态成员的初始化

测试调用

void testLazySingleton()
{
	//LazySingleton lazySingleton;			//编译不过,构造函数私有化不能在类定义的外部创建类的实例
	//LazySingleton* p1 = new LazySingleton;//编译不过,因为右值要触发在堆上创建类的实例对象,并调用构造函数初始化
	//LazySingleton* p2;//可以,因为它并不会创建类的对象,只是定义了一个类类型的指针变量

	LazySingleton* f1 = LazySingleton::getSingleton();
	LazySingleton* f2 = LazySingleton::getSingleton();
	if(f1 == f2)
	{
		cout << "f1 和 f2 指向的内存地址相同" << endl;
	}else {
		cout << "f1 和 f2 指向的内存地址不相同" << endl;
	}
}
int main(int argc, char *argv[])
{
	cout << "main function ...." << endl;
	testLazySingleton();
	return 0;
}

编译命令:g++ -std=c++11 singleton.cpp -o singleton
打印输出
在这里插入图片描述

饿汉式

代码示例如下:

HungrySingleton类

#include <iostream>
using namespace std;
class HungrySingleton
{
private:
	HungrySingleton(){ cout << "HungrySingleton constructor" << endl;};//保证构造函数私有
	~HungrySingleton(){};//析构函数私有
public:
	static HungrySingleton* getSingleton()
	{
		return singleton;
	}
private:
	static HungrySingleton* singleton;//声明
};

//定义静态成员变量
HungrySingleton*  HungrySingleton::singleton = new HungrySingleton;//在main函数执行前会进行静态成员的初始化,会调用HungryFactory类的私有构造函数初始化对象
//上面这一句,右值为啥可以写new HungryFactory,因为这句静态成员变量的定义,相当于它仍然在类的作用域范围内。可以访问到私有构造函数。

测试调用

void testHungrySingleton()
{
	//HungrySingleton hungrySingleton;//编译不过,构造函数私有化不能在类定义的外部创建类的实例
	//HungrySingleton* p3 = new HungrySingleton;//编译不过,同上
	//HungrySingleton* p4;//可以,因为它并不会创建类的对象,只是定义了一个类类型的指针变量

	HungrySingleton* f3 = HungrySingleton::getSingleton();
	HungrySingleton* f4 = HungrySingleton::getSingleton();
	if(f3 == f4)
	{
		cout << "f3 和 f4 指向的内存地址相同" << endl;
	}else {
		cout << "f3 和 f4 指向的内存地址不相同" << endl;
	}
}

int main(int argc, char *argv[])
{
	cout << "main function ...." << endl;
	testHungrySingleton();
	return 0;
}

编译命令:g++ -std=c++11 singleton.cpp -o singleton
打印输出
在这里插入图片描述
懒汉式的特点:
1.私有化构造函数和析构函数。
2.定义一个单例对象的类类型指针的静态成员变量,并指向空地址。
3.提供静态获取单例对象的函数
饿汉式的特点:
1.私有化构造函数和析构函数。
2.定义一个单例对象的类类型指针的静态成员变量,并初始化为单例对象。
3.提供静态获取单例对象的函数。

两者的不同点:
懒汉式 是在程序中首次需要时才进行单例对象的生成,生成的时期是在main函数执行后。
饿汉式 是在程序加载时进行的静态成员变量的初始化生成的,生成的时期是在main函数执行前。
懒汉式 是线性不安全的,而饿汉式是线程安全的。

关于单例对象的内存释放问题:
由于整个程序运行期间 都是公用这个类的一个实例对象。私有化析构函数的目的就是防止人为手动删除单例对象,以至于
别人获取时出现失败。故而不提供公用的析构函数,那么堆内的这个单例对象,只有在程序结束时,由操作系统进行单例
对象内存回收,不用担心会发生内存泄漏,因为这个类的实例对象 自始至终只有一份,占不了多大内存。因为内存泄漏的
发生原因是指的堆中非单例对象,不断地创建新对象,程序不再使用时,也没有手动干预进行堆内存释放。导致日积月
累,堆内存被占用完毕,进而发生堆内存泄漏。
内存泄漏 只发生于 堆内存。这里所说的内存泄漏 都是指的堆内存泄漏。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/302184.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

轻量级VS Code运行HTML代码不是难事,这里提供几个方法

对于那些刚开始编码的人来说,Visual Studio Code(VS Code)是更大、更复杂的代码编辑器的一个很好的替代品。特别是对于网络开发人员来说,它提供了许多编写和调整HTML部分的机会,加上大量的功能,使开发成为一次激动人心的旅程。 但是,如果你是开发界的新手,那么你究竟是…

Vue3-37-路由-组件内的路由守卫 onBeforeRouteLeave 和 onBeforeRouteUpdate

简介 组件内的路由守卫&#xff0c;实际上就是两个 API 方法。 他们与普通的守卫不同的是 &#xff1a; 他们是写在组件内的&#xff0c;在组件中监听路由的变化&#xff0c;不是全局的&#xff0c;比较灵活。 以下是两个 API 的功能说明&#xff1a;onBeforeRouteLeave() : 守…

SpringBoot项目如何防止反编译?

SpringBoot项目如何防止反编译&#xff1f; 场景方案项目操作启动方式反编译效果绑定机器启动 场景 最近项目要求部署到其他公司的服务器上&#xff0c;但是又不想将源码泄露出去。要求对正式环境的启动包进行安全性处理&#xff0c;防止客户直接通过反编译工具将代码反编译出…

x-cmd pkg | busybox - 嵌入式 Linux 的瑞士军刀

目录 简介首次用户功能特点竞品和相关作品 进一步阅读 简介 busybox 是一个开源的轻量级工具集合&#xff0c;集成了一批最常用 Unix 工具命令&#xff0c;只需要几 MB 大小就能覆盖绝大多数用户在 Linux 的使用&#xff0c;能在多款 POSIX 环境的操作系统&#xff08;如 Linu…

二叉树题目:好叶子结点对的数量

文章目录 题目标题和出处难度题目描述要求示例数据范围 解法思路和算法代码复杂度分析 题目 标题和出处 标题&#xff1a;好叶子结点对的数量 出处&#xff1a;1530. 好叶子结点对的数量 难度 6 级 题目描述 要求 给定二叉树的根结点 root \texttt{root} root 和整数 …

LIN总线与CAN总线的传输方式有什么不同?

​ 关注菲益科公众号—>对话窗口发送 “CANoe ”或“INCA”&#xff0c;即可获得canoe入门到精通电子书和INCA软件安装包&#xff08;不带授权码&#xff09;下载地址。 LIN&#xff0c;Interconnect Network&#xff0c;适用于速度和可靠性要求不高、低成本的场合&#xff…

TS 36.211 V12.0.0-通用功能

本文的内容主要涉及TS 36.211&#xff0c;版本是C00&#xff0c;也就是V12.0.0。

【cmu15445c++入门】(2)c++中的std::move() 左值引用右值引用

左值右值 要理解move语义&#xff0c;必须理解左值和右值的概念。左值的简化定义是左值是对象&#xff0c;指向内存中某个位置。右值是左值之外的任何。 std::move() move语义&#xff0c;在C中是一个有用的方法&#xff0c;它允许在对象之间高效和优化地转移数据所有权。m…

计算机创新协会冬令营——暴力枚举题目06

我给大家第一阶段的最后一道题就到这里了&#xff0c;下次得过段时间了。所以这道题简单一点。但是足够经典 下述题目描述和示例均来自力扣&#xff1a;两数之和 题目描述 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target …

基于SpringBoot微信小程序的宠物美容预约系统设计与实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行交流合作✌ 主要内容&#xff1a;SpringBoot、Vue、SSM、HLM…

学校服务器安装anaconda并配置pytorch环境

学校服务器安装anaconda并配置pytorch环境 1.下载Anaconda2.传到xftp中3.在终端运行脚本命令4.安装pytorch4.1 查看cuda版本4.2 创建自己的环境4.3 下载pytorch4.4 验证pytorch是否安装成功 参考视频&#xff1a;远程服务器安装anaconda并配置pytorch环境 使用服务器运行项目&a…

Kafka(五)生产者

目录 Kafka生产者1 配置生产者bootstrap.serverskey.serializervalue.serializerclient.id""acksallbuffer.memory33554432(32MB)compression.typenonebatch.size16384(16KB)max.in.flight.requests.per.connection5max.request.size1048576(1MB)receive.buffer.byte…

UE5.1报错 | C2628: “SNormalDistributionWidget”后面接“void”是非法的(是否忘记了“;”?)

UE5.1报错 | C2628: “SNormalDistributionWidget”后面接“void”是非法的(是否忘记了“;”?) 报错&#xff1a; UE5.1报错 | C2628: “SNormalDistributionWidget”后面接“void”是非法的(是否忘记了“;”?) 解决&#xff1a; 检查定义类的时候&#xff0c;反花括号“…

[每周一更]-(第82期):选购NAS中重要角色RAID

网络附加存储&#xff08;NAS&#xff09;在现代数字生活中扮演着至关重要的角色&#xff0c;而对于NAS的选择中&#xff0c;关注RAID的重要性更是不可忽视的。 数据存储和安全越来越受关注&#xff1b; 为什么要使用NAS&#xff1f; 集中式存储&#xff1a; NAS提供了一个集中…

利用Python实现每日新闻早报推送

本文将介绍如何使用Python编写简单的逻辑&#xff0c;通过调用API接口实现每日新闻推送功能。 步骤&#xff1a; 导入所需的库&#xff1a; 在代码的开头&#xff0c;我们需要导入所需的库。通常&#xff0c;我们会使用requests库来发送HTTP请求&#xff0c;以获取新闻数据。 …

全栈自动化测试面试题含答案和学习路线(适合各级软件测试人员)

在面试战场上&#xff0c;我们需要像忍者一样灵活&#xff0c;像侦探一样聪明&#xff0c;还要像无敌铁金刚一样坚定。只有掌握了这些技巧&#xff0c;我们才能在面试的舞台上闪耀光芒&#xff0c;成为那个令HR们心动的测试人 前言&#xff1a; 我相信大多测试开发的或多或少经…

用户管理第2节课--idea 2023.2 后端--实现基本数据库操作(操作user表) -- 自动生成 --合并生成后的代码【鱼皮】

一、模块页面功能 1.1 domain 【实体对象】 1.2 mapper 【操作数据库的对象】--> UserMapper 1&#xff09;UserMapper 其实就是我们用来操作数据库的一个对象 2) 继承了mybatis- plus&#xff0c;它会自动帮我们去定义一些增删改查的方法。 继承可以看下图&#xf…

数据结构线性表之顺序表

一、线性表及顺序表概念 1.线性表的概念&#xff1b; 线性表是零个或多个具有相同特性的数据元素组成的有限序列&#xff0c;线性表是实际中&#xff0c;广泛使用的一种数据结构&#xff0c;相关的有&#xff1a;顺序表&#xff0c;链表&#xff0c;栈&#xff0c;队列&#…

Python私有变量的定义与访问

class Student():def __init__(self, name, age):self.name nameself.age ageself.__score 0def marking(self, score):if score < 0:return 分数不能为0self.__score scoreprint(self.name 同学本次得分是: str(self.__score)) def __talk(self): # 私有的类可通过在…

如果你创业总失败,不妨看看爷叔是如何创业的!未来三年最大创业风口,2024普通人怎么创业

自从央视点评《繁花》“剧”有强调之后&#xff0c;该电视剧的播放量就节节高升。同时&#xff0c;剧中精彩的商业的大战让人们直呼过瘾&#xff0c;其中的爷叔准确的商业眼光&#xff0c;经典的商业理论也让许多创业者得到了启示。 一、爷叔创业语录 1、做生意要讲究“派头、…