C++:继承

C++:37---继承概念、继承种类 这篇文章不详细分析继承和不同继承关系下的特点。我将在后边几篇文章里专门针对继承关系来做分析。一、基类与派生类的概念基类(父类):在继承关系中处于上层的类派生类(子类):在继承关系中处于下... 阅读详情

一、继承的概念及定义

1.1 继承的概念

 继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段之一。
 继承是在已有类的基础上派生出新类,新类可以在保持原有类特性的基础上进行扩展,增加新的属性和方法。原有类被称为父类、基类;新类被称为子类或派生类!继承可以提高代码的复用性,呈现出面对面向对象程序设计的层次结构。

【实例】:

class Person
{
public:
	void Print()
	{
		cout << "name:" << _name << endl;
 		cout << "age:" << _age << endl;
 	}
protected:
 	string _name = "peter"; // 姓名
 	int _age = 18;  // 年龄
};

// 继承后父类的Person的成员函数和成员变量都变成子类的一部分
class Student : public Person
{
protected:
 	int _stuid; // 学号
};

int main()
{
	 Student s;
	 s.Print();
	 return 0;
}

1.2 继承格式和继承属性

1)、 继承格式

 下面我们看到Person是父类,也称作基类。Student是子类,也称作派生类。继承方式和访问限定符一样,有三种:public继承、protected继承、private继承!
在这里插入图片描述

2)、继承关系和访问方式变化

 继承和访问限定符分类如下:

在这里插入图片描述

 继承方式的不同,必然会导致访问方式的变化,具体如下:

类成员/继承方式public继承protected继承private继承
基类的public成员派生类的public成员派生类的protected成员派生类的private成员
基类的protected成员派生类的protected成员派生类的protected成员派生类的private成员
基类的private成员在派生类中不可见在派生类中不可见在派生类中不可见
  1. 基类private成员在派生类中无论以什么方式继承都是不可见的。这里的不可见是指基类的私有成员还是被继承到了派生类对象中,但是语法上限制派生类对象不管在类里面还是类外面都不能去访问它。
  2. 基类private成员在派生类中是不能被访问,如果基类成员不想在类外直接被访问,但需要在派生类中能访问,就定义为protected。保护成员限定符是因继承才出现的。
  3. 基类的私有成员无论如何派生类都无法访问,至于其他组合方式,访问方式是基类成员访问限定符和继承方式的较小方式。(public > protected > private)
  4. 使用关键字class时默认的继承方式是private,使用struct时默认的继承方式是public,不过最好显示的写出继承方式。
    .

二、基类和派生类对象赋值转换

 相似类型对象支持相互转换,并且中间会生成一个临时变量。比如:int和double都表示数,只是精度的问题罢了,所以支持赋值转换。
【实例】:

int main()
{
//为什么i加引用,不加const会报错.
//原因在于赋值转化时,首先会将变量d转化为int类型并将结果存在一个临时变量里
//所以这里引用绑定的对象实际是这个临时变量,所以必须加const,否则会编译报错。
	double d = 1.2;
	//int& i = d; //error
	const int& i = d;
	return 0;
}

 但在基类和派生类对象之间的赋值转换不会产生临时变量。子类对象赋值给父类对象/父类指针/父类的引用,我们认为这是天然的,中间不产生临时变量,这个叫做父子类赋值兼容规则(或切割、切片)
在这里插入图片描述

  1. 在public继承中,父类和子类是一个is-a关系。
  2. 基类对象不能赋值给派生类对象。
  3. 基类的指针或者引用可以通过强制类型转换赋值给派生类的指针或者引用。但是必须是基类的指针是指向派生类对象时才是安全的。这里基类如果是多态类型,可以使用RTTI(RunTime Type Information)的dynamic_cast 来进行识别后进行安全转换。

【实例验证】

class Person
{
protected:
	string _name; // 姓名
	string _sex;  // 性别
	int	_age;	 // 年龄
};

class Student : public Person
{
public:
	int _No; // 学号
};

int main()
{
	Student s;
	Person p = s;
	Person& rp = s;
	return 0;
}

我们运行这段代码发现可以正常通过,也从侧面说明基类和派生类对象之间的赋值转换不会产生临时变量。

三、继承中的作用域

继承中的作用域主要就注意以下这几点就可以了。

  1. 在继承体系中基类和派生类都有独立的作用域。所以父类和子类中同名函数不会构造函数重载!
  2. 子类和父类中有同名成员,子类成员将屏蔽父类对同名成员的直接访问,这种情况叫隐藏,也叫重定义;如果是成员函数的隐藏,只需要函数名相同就构成隐藏!!
  3. 但即使构成隐藏,我们可以通过( 基类::基类成员)显示访问基类成员。

【实例】:

// B中的fun和A中的fun不是构成重载,因为不是在同一作用域
// B中的fun和A中的fun构成隐藏,成员函数满足函数名相同就构成隐藏。
class A
{
public:
	void fun()
	{
		cout << "func()" << endl;
	}
};

class B : public A
{
public:
	void fun(int i)
	{
		A::fun(); //显示访问基类成员
		cout << "func(int i)->" << i << endl;
	}
};

void Test()
{
	B b;
	b.fun(10);
};

四、派生类的默认成员函数

6个默认成员函数,即我们不写,编译器会变我们自动生成一个,那么在派生类中,这几个成员函数是如何生成的呢?

  1. 派生类的构造函数必须调用基类的构造函数初始化基类的那一部分成员。如果基类没有默认的构造函数,则必须在派生类构造函数的初始化列表阶段显示调用。
  2. 派生类的拷贝构造函数必须调用基类的拷贝构造完成基类的拷贝初始化。
  3. 派生类的operator=必须要调用基类的operator=完成基类的复制。
  4. 派生类的析构函数会在被调用完成后自动调用基类的析构函数清理基类成员。因为这样才能保证派生类对象先清理派生类成员再清理基类成员的顺序。
  5. 派生类对象初始化先调用基类构造再调派生类构造。
  6. 对于析构函数,编译器会对析构函数名进行特殊处理,处理成destrutor(),所以父类析构函数不加virtual的情况下,子类析构函数和父类析构函数构成隐藏关系。


【实例】:(下面主要演示4个主流的默认构造函数,至于其他2个基本没用)

class Person
{
public:
	Person(const char* name = "peter")
		: _name(name)
	{
		cout << "Person()" << endl;
	}

	Person(const Person& p)
		: _name(p._name)
	{
		cout << "Person(const Person& p)" << endl;
	}

	Person& operator=(const Person& p)
	{
		cout << "Person operator=(const Person& p)" << endl;
		if (this != &p)
			_name = p._name;

		return *this;
	}

	~Person()
	{
		cout << "~Person()" << endl;
	}
protected:
	string _name; // 姓名
};

class Student : public Person
{
public:

	//按照声明顺序完成构造,先调用基类的默认构造,在初始化其他成员
	//由于基类Person中有默认构造,所以也可以不显示调用
	Student(const char* name, int id)
		:_id(id)
		, Person(name)
	{
		cout << "Student(const char* name, int id)" << endl;
	}

	//派生类拷贝构造,基类的成员变量的拷贝构造必须调用基类的拷贝构造
	Student(const Student& s)
		:Person(s)
		, _id(s._id)
	{
		cout << "Student(const Student& s)" << endl;
	}

	//派生类赋值重载中的基类成员必须调用基类的赋值重载函数
	//由于派生类和基类的赋值重载构成隐藏,所以我们必须显示指定类域调用对应的赋值重载
	Student& operator=(const Student& s)
	{
		if (&s != this)
		{
			Person::operator=(s);//显示指定调用
			_id = s._id;
		}

		cout << "Student& operator=(const Student& s)" << endl;
		return *this;
	}

	// 由于多态的原因,析构函数统一会被处理成destructor
	// 父子类的析构函数构成隐藏
	// 为了保证析构安全,先子后父
	// 父类析构函数不需要显示调用,子类析构函数结束时会自动调用父类析构
	// 保证先子后父
	~Student()
	{
		cout << "~Student()" << endl;
	}

protected:
	int _id;
};

int main()
{
	Student s1("张三", 18);
	Student s2(s1);

	Student s3("李四", 19);
	s1 = s3;


	return 0;
}

五、继承与友元、静态成员

1)、继承与友元

 友元关系不能继承,也就是说基类友元不能访问子类私有和保护成员。

2)、继承与静态成员

 基类定义了static静态成员,则整个继承体系里面只有一个这样的成员。静态成员和成员函数一样只有一份,子类只是继承了使用权。

【实例】:(统计定义了多少个对象,都是继承关系)
【分析】:我们可以定义一个静态变量,由于是继承关系,所有对象的默认构造是都需要调用子类的默认构造来初始化对象中子类的成员。所以我们可以在最开始的类中显示的写默认构造函数 + 定义静态变量,同时每运行一次说明创建了一个对象,将静态变量++即可。
【代码】:

class Person
{
public:
	Person() 
	{
		++_count; 
	}
public:
	static int _count; // 统计人的个数。
};
int Person::_count = 0;//定义

class Student : public Person
{
protected:
	int _stuNum; // 学号
};


int main()
{
	Student s1;
	Person p1;
	cout << " 人数 :" << Person::_count << endl;
	Student s2;
	Student s3;
	cout << " 人数 :" << Person::_count << endl;

	return 0;
}

在这里插入图片描述

六、菱形继承、菱形虚拟继承

 继承分为单继承和多继承。而菱形继承是多继承的一直特殊情况,虚拟继承则是为了解决其中的一些问题孕育而生。
单继承:一个子类只有一个直接父类时称这个继承关系为单继承。
在这里插入图片描述
多继承:一个子类有多个直接父类时称这个继承关系为多继承。
在这里插入图片描述
菱形继承:存在多个子类继承同一个父类;而最终一个类同时继承这些派生类!!
在这里插入图片描述

6.1 菱形继承的问题

我们来看看这个继承类:

class Person
{
public:
	string _name; // 姓名
};

class Student : public Person
{
protected:
	int _num; //学号
};

class Teacher : public Person
{
protected:
	int _id; // 职工编号
};

class Assistant : public Student, public Teacher
{
protected:
	string _majorCourse; // 主修课程
};

【关系如下】:

在这里插入图片描述 菱形继承存在数据冗余和二义性的问题(Assistant的对象中Person成员会有两份)由于二义性,当我们直接通过a._name = "xxx"去修改数据时,我们没法确定访问的是哪一个。

6.2 二义性解决办法(1) —— 指定类域显示访问

 要显示指定访问哪个父类的成员可以解决二义性问题,但是数据冗余问题无法解决。

a.Student::_name = "xxx";
a.Teacher::_name = "yyy";

6.3 二义性解决办法(2)—— 虚拟继承

 在上面的继承关系中,在Student和Teacher的继承Person时使用虚拟继承(在继承方式前加virtual关键字),即可解决问题。需要注意的是,虚拟继承不要在其他地方去使用。
【实例】:

class Person
{
public:
	string _name; // 姓名
};

class Student : virtual public Person
{
protected:
	int _num; //学号
};

class Teacher : virtual public Person
{
protected:
	int _id; // 职工编号
};

class Assistant : public Student, public Teacher
{
protected:
	string _majorCourse; // 主修课程
};

void Test()
{
	Assistant a;
	a._name = "peter";
}

6.4 虚拟继承解决数据冗余和二义性的原理

接下来所有分析都基于以下代码:

class A
{
public:
	int _a;
};

 class B : public A
//class B : virtual public A
{
public:
	int _b;
};

 class C : public A
//class C : virtual public A
{
public:
	int _c;
};
class D : public B, public C
{
public:
	int _d;
};
int main()
{
	D d;
	d.B::_a = 1;
	d.C::_a = 2;
	d._b = 3;
	d._c = 4;
	d._d = 5;
	return 0;
}

下图是菱形继承的内存对象成员模型:这里可以看到数据冗余

在这里插入图片描述
下图是菱形虚拟继承的内存对象成员模型:这里可以分析出D对象中将A放到的了对象组成的最下面,这个A同时属于B和C,那么B和C如何去找到公共的A呢?这里是通过了B和C的两个指针,指向的一张表。这两个指针叫虚基表指针,这两个表叫虚基表。虚基表中存的偏移量。通过偏移量可以找到下面的A。
在这里插入图片描述
下面是上面的Person关系菱形虚拟继承的原理解释:
在这里插入图片描述
总结:多继承可以认为是C++的缺陷之一,很多后来的OO语言都没有多继承,如Java。

七、继承和组合

  1. public继承是一种is-a的关系。也就是说每个派生类对象都是一个基类对象。组合是一种has-a的关系。假设B组合了A,每个B对象中都有一个A对象。
  2. 优先使用对象组合,而不是类继承
  3. 继承允许你根据基类的实现来定义派生类的实现。这种通过生成派生类的复用通常被称为白箱复用(white-box reuse)。术语“白箱”是相对可视性而言:在继承方式中,基类的内部细节对子类可见 。继承一定程度破坏了基类的封装,基类的改变,对派生类有很大的影响。派生类和基类间的依赖关系很强,耦合度高。
  4. 对象组合是类继承之外的另一种复用选择。新的更复杂的功能可以通过组装或组合对象来获得。对象组合要求被组合的对象具有良好定义的接口。这种复用风格被称为黑箱复用(black-box reuse),因为对象的内部细节是不可见的。对象只以“黑箱”的形式出现。组合类之间没有很强的依赖关系,耦合度低。优先使用对象组合有助于你保持每个类被封装。
  5. 实际尽量多去用组合。组合的耦合度低,代码维护性好。不过继承也有用武之地的,有些关系就适合继承那就用继承,另外要实现多态,也必须要继承。类之间的关系可以用继承,可以用组合,就用组合。
C++:13---继承(单一继承、多重继承、多级继承、菱形继承、虚继承) 一、基类与派生类的概念基类(父类):在继承关系中处于上层的类派生类(子类):在继承关系中处于下层的类class A;class B;class C:public A //C为A的子类,... 阅读详情

相关推荐

C++之继承探究(三):继承的方式

前文:C++之继承探究(一) 继承方式   子类继承父类后,继承下来的成员的访问权限不能被子类提升,父类中的private成员被子类继承后依然是private成员,父类中的protected成员在子类中可以是protected和private,父类中的public成员在子类中可以是public、protected和private。 子类中被继承的成员访问级别由三种继承说明符决定:   (1) 私有(private)继承;所有被继承的成员在子类中都是private。   (2) 保护(protected)继承

小勇博客 425

继承与多态实战:CPP-Crash-Course中的高级C++特性

在C++编程中,继承与多态是面向对象编程的核心特性,它们能够显著提升代码的复用性和扩展性。CPP-Crash-Course项目通过清晰的示例代码,展示了如何在实际开发中应用这些高级特性。本文将带你深入理解继承与多态的概念,并通过项目中的实例代码,掌握它们的实际应用技巧。 ## 继承:代码复用的基石 继承允许我们创建新类(派生类)来继承现有类(基类)的属性和方法,从而实现代码的复用和扩展。在CP

gitblog_00025的博客 820

西门子触摸屏教程wincc flexible2008 sp5 Smart V3 V4中文版软件

西门子触摸屏教程wincc flexible2008 sp5 Smart V3 V4中文版软件

liang007dudu的博客 1万+

【C++ 泛型编程 入门篇】全面掌握C++元模板中的模板继承:模板继承深入指南和教程

在C++中,继承通常是面向对象编程的一个特性,用于创建基于现有类的新类。然而,这个概念也可以应用于模板。通过模板继承,我们可以创建一个基于现有模板的新模板,并且可以为新模板添加或覆盖特定的功能。

探索C++编程的奥秘,分享深入的技术见解和实践,旨在激发读者创造力与解决问题的思维。 1987

运维与软件实施课表

运维与软件实施课表 课程 章节编号 章节 课程地址 软件及操作系统基础 ch01 软件及操作系统基础01 实施、运维工程师基本技能:https://blog.youkuaiyun.com/qq_28189423/article/details/82700539 老毛桃制作winPE镜像:https://blog.youkuaiyun.com/qq_2818942...

Mr.O~的博客 1万+

【鸿蒙南向开发】OpenHarmony——分布式数据对象之功能实践

通过本文的学习可了解到分布式数据对象的主要接口、大致调用方法和功能实现等。结合对应内容,可以进一步对分布式数据对象同步机制做深度学习。下一步,(1) 着重理解同步组网的构建原理。(2) 着重理解同步组网内,监听change和status变化的实现。●如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:●关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。

HarmonyOS_666的博客 1090

Cherno的Cpp教程笔记011:C++继承+虚函数

private,

ResumeProject的博客 281

PCL Fast Global Registration 快速全局配准(源码版)

Fast Global Registration(FGR)是一种经典的点云粗配准算法,已集成到Open3D和CloudCompare等软件中。本文介绍了该算法的源码实现及优化方法,包括如何通过修改源码直接读取点云进行配准,而不依赖文件中读取特征描述子。文章还提供了关键参数设置(如最大迭代次数、匹配距离等)。算法实现简单高效,未来计划发布基于纯PCL的版本。源码和论文链接已附上,供开发者参考。

点云侠的博客 383

C++:继承

本文系统介绍了C++继承机制的核心概念与应用。首先阐述了继承的基本概念、定义方式及其访问控制规则,重点分析了基类与派生类间的转换规则和作用域问题。其次详细讲解了派生类默认成员函数的生成规则,包括构造、拷贝构造、赋值重载和析构函数的实现要点。接着探讨了两种实现不可继承类的方法,以及继承与友元、静态成员的关系。最后深入剖析了多继承中的菱形继承问题及其解决方案,对比了继承与组合的优缺点,强调实践中应优先使用组合。全文通过丰富代码示例,全面展示了继承机制在面向对象程序设计中的关键作用。

2301_78901562的博客 1万+

pycharm一直选择不了conda正确路径弹框报错:latinit property envs_dirs has not been initialized...如何解决?

🏆本文收录于 《全栈 Bug 调优(实战版)》 专栏。专栏聚焦真实项目中的各类疑难 Bug,从成因剖析 → 排查路径 → 解决方案 → 预防优化全链路拆解,形成一套可复用、可沉淀的实战知识体系。无论你是初入职场的开发者,还是负责复杂项目的资深工程师,都可以在这里构建一套属于自己的「问题诊断与性能调优」方法论,助你稳步进阶、放大技术价值 。

**My Coding Family** 2917

【AI智能体】Claude Code +Superpowers 项目实战操作详解

Claude Code +Superpowers 项目实战操作详解

congge 4047

Cpp深入:多重继承

Worker.h #ifndef _WORKER_H_ #define _WORKER_H_ #include &lt;iostream&gt; class Worker { // 基类 public: Worker(); // 这里需要设置成虚函数 virtual ~Worker(); }; class Waiter : virtual public Worker...

omygege 232

2022年全国职业院校技能大赛 高职组大数据技术与应用卷⑦——解析答案

大数据时代,电商经营模式发生很大改变。在传统运营模式中,缺乏数据积累,人们在做出一些决策行为过程中,更多是凭借个人经验和直觉,发展路径比较自我封闭。而大数据时代,为人们提供一种全新的思路,通过大量的数据分析得出的结果将更加现实和准确。商家可以对客户的消费行为信息数据进行收集和整理,比如消费者购买产品的花费、选择产品的渠道、偏好产品的类型、产品回购周期、购买产品的目的、消费者家庭背景、工作和生活环境、个人消费观和价值观等。通过数据追踪,知道顾客从哪儿来,是看了某网站投放的广告还是通过朋友推荐链接,是新访客还是

我是网络安全兼技能大赛工程师,专注网络安全技术学习与技能大赛实战!持续分享最新的技术文章,帮你少走弯路,一起在技术赛道上进步~ 471

C++:public继承、protected 继承、private继承

C++中常见的3种继承方式:public 继承、protected 继承和private继承public 当采用公有继承时,基类成员对其对象的可见性与一般类及其对象的可见性相同,公有成员课件,其他成员不可见。基类成员对派生类的可见性对派生类来说,基类的公有成员和保护成员可见;基类的公有成员和保护成员作为派生类的成员时,它们都维持原有的状态;基类的私有成员不可见;基类的私有成员依然是私有的,派生类

梦里水乡的专栏 1305

硬件工程师学习-硬件的单元测试(UT)(1)电源与时钟的测试

我们在设计的时候,通过控制电源的上电使能管脚或者通过MOSFET、或者专用的电源上电控制芯片,控制不同电源的上电时序,以确保每个芯片的电源上电时序是满足芯片的要求的。我们在测试的时候,需要对相关的要求一一测试,以确认每个上电时序满足要求的。在维基百科中,相位噪声的定义是“时域不稳定性(抖动)导致波形在相位上发生快速、短期、随机的波动,这种波动在频域中的表现即为相位噪声”。单元测试,一般是指基于开发人员自行开展的功能测试及各个功能单元的单元测试,是硬件信号级的测试,分为基本测试和信号完整性测试。

qq_43416206的博客 4033

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

C++中的代码重用:包含 私有继承 以及 多重继承

公有继承是实现代码重用目标的方式之一,同时还有一种方法:使用本身是另外一个类的对象的类成员,简单的说就是一个类的成员包含用另外一个类创建的对象,这种方法被称为包含(containment)、组合(composition)或层次化(layering);还有一种方法是使用私有继承或保护继承,用于实现has-a关系。 一、包含对象成员的类: 1、valarray类 valarry由头文件valarray支持,是一个定义的模板类,用于处理数值,或具有类似性质的类,支持:max()、m...

Ho_mu_ra的博客 1018

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

C++的三种继承方式:public,protected,private

C++访问权限控制符 : public 公有成员 基类、派生类、友元、外部都可以访问 protected 保护成员 基类、派生类、友元可以访问 private 私有成员 基类、友元可以访问 同样的C++继承方式有public,protected,private三种: 今天就来给大家简单介绍一下C++的三种继承方式。 1、public 方式继承 基类成员对派生类的可见性对派生类来说,基类的公有成员和保护成员可见,基类的公有成员和保护成员...

Hsuesh的博客 2921

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

C++:继承(1)——public、protected、private继承

文章目录类的public、protected、private继承public继承:基类public、protected、private的访问权限参考链接 类的public、protected、private继承 / public继承 protected继承 private继承 基类public成员 public protected 不可见 ❌ 基类protected成员 pr...

weixin_41442027的博客 3195

C++:继承方式

一共有三种: 公共继承 保护继承 私有继承 父类中的private类,子类都不能继承 公共权限继承,到了子类中父类的权限没有变化 保护继承,到了子类中继承到的父类的权限全变为保护权限 私有继承,,到了子类中继承到的父类的权限全变为私有权限 公共: class Base1 { public: int m_A; protected: int m_B; private: int m_C; }; //公共继承 class Son1 :public Base1 { public:

咩咩的博客 135

C++继承进阶:友元、静态与菱形继承解析

友元:关系不继承,需在派生类中显式声明。静态成员:共享但可重定义,存储在全局区。菱形继承:通过虚继承解决,使用虚表管理共享基类偏移,优化内存。通过这些概念,你可以更深入地理解C++继承的复杂行为。在实际开发中,优先使用虚继承避免菱形问题,并谨慎管理友元和静态成员。如果有更多问题,欢迎进一步探讨!

q_438141的博客 523

cpp学习笔记:继承

cpp学习

ohhjack的博客 815

C++继承标号:public继承、protected继承、private继承

C++继承标号:public继承、protected继承、private继承 继承标号确定了成员或者成员函数在派生类中的访问权限。 //Base class class base{ public:     int a=0;     int ret_value(){return a;} private:     int b=0; }; //public der

haveagoodjob的专栏 524
上一篇: C++:stack、queue、priority_queue增删查改模拟实现、deque底层原理
下一篇: C++:多态究竟是什么?为何能成为面向对象的重要手段之一?
小白debug~
小白debug~ 新星创作者: C/C++技术领域 新星创作者: C/C++技术领域
博客等级 码龄4年 3510粉丝 128原创
评论 119
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白debug~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值