C++面向对象程序设计 - 继承与派生进一步讨论

news2024/11/23 11:57:17

        C++中所谓“继承”就是在一个已存在的类的基础上建立一个新类,从已有的类那里获得已有特性,叫做类的继承。从另一角度说,从已有的类(父类)产生一个新的子类,称为类的派生。一个派生类只从一个基类派生,这称为单继承;一个派生类有两个或多个基类,称为多继承。派生类是基类的具体化,而基类则是派生类的抽象。

        该篇将通过一些习题进一步了解继承与派生。

一、私有、保护、公有成员的公有继承的访问权限

        在C++中,对于派生类对象,不能直接通过派生类对象来引用基类的私有(private)成员,因为私有成员只能在类自身内部访问,而不能从外部(包括派生类)访问;保护(protected)成员虽然在类外部不可见,但是它们在派生类内部是可见的。此时我们将通过公有继承案例来了解下它们之间关系。

        在以下程序结构中,分析问题,代码如下:

class A{
	public:
		void f1(){}
		int i;
	protected:
		void f2(){}
		int j;
	private:
		int k;
};
class B: public A{
	public:
		void f3(){}
	protected:
		int m;
	private:
		int n;	
};
class C: public B{
	public:
		void f4(){}
	private:
		int p;
};
int main(){
	A a1;			// a1 是基类A的对象
	B b1;			// b1 是派生类B的对象
	C c1;			// c1 是派生类C的对象
	return 0;
}

1.1 派生类访问基类中数据成员

问题:在main函数中能否用b1.i,b1.j和b1.k引用派生类B对象b1中基类A的成员?

回答:

  • b1.i是可以的,因为i是公有的。
  • b1.j是不可以的,因为j为保护成员,只能在派生类或基类中访问,无法在类外部直接访问
  • b1.k是不可以的,因为k为私有成员,只能在基类中访问。

1.2  派生类访问基类中成员函数

问题:派生类B中的成员函数能否调用基类A中的成员函数f1和f2?

回答:可以,因为基类A中f1()为公有(public)成员函数,派生类B的成员函数可以直接调用它;f2()为保护(protected)成员函数,派生类B的成员函数也可以调用它。

1.3 派生类成员函数访问基类中数据成员

问题:派生类B中的成员函数能否引用基类A中的数据成员i,j,k?
回答:对于公有(public)数据成员i 和 保护(protected)数据成员j,派生类B的成员函数是可以直接引用它,但是对于基类A中私有(private)数据成员k,只能在基类A内部访问,派生类B的成员函数不能直接引用它,否则会报错【[Error] 'int A::k' is private within this context】- 在这个上下文中,'int A::k是私有的'。

1.4 多层派生类访问数据成员

问题:能否在main函数中用c1.i,c1.j,c1.k,c1.m,c1.n,c1.p引用基类A的成员i,j,k,派生类B的成员m,n,以及派生类C的成员p?
回答:

  • c1.i是可以的,因为i是基类A的公有数据成员。
  • c1.j是不可以的,因为j是基类A的保护数据成员,只能在基类A和派生类B、C内部访问。
  • c1.k是不可以的,因为k是基类A的私有数据成员,只能基类A内部访问
  • c1.m是不可以的,因为m是基类B的保护数据成员,只能在基类B和派生类C内部访问。
  • c1.n是不可以的,因为n是基类B的私有数据成员,只能在基类B内部访问。
  • c1.p是不可以的,因为p是派生类C的私有数据成员,只能在派生类C内部访问。

1.5 多层派生类访问成员函数

问题:能否在main函数中用c1.f1(),c1.f2(),c1.f3()和c1.f4(),调用f1,f2,f3,f4成员函数?
回答:

  • c1.f1()是可以的,因为函数f1()是基类A的公有成员函数。
  • c1.f2()是不可以的,因为函数f2()是基类A的保护成员函数,只能在基类A内部或派生类B、C内部访问。
  • c1.f3()是可以的,因为函数f2()是派生类C的基类B的公有成员函数。
  • c1.f4()是可以的,因为函数f4()是派生类C的公有成员函数。

1.6 多层派生类内部访问成员函数

问题:派生类C的成员函数f4能否调用基类A中的成员函数f1,f2和派生类中的成员函数f3?

回答:可以的,因为函数f1(),f2()在基类A中为公有和保护成员函数,可以在派生类C的内部直接调用。

二、私有、保护、公有继承的成员访问权限

问题:分析以下程序的所有成员在各类的范围的访问权限,代码如下:

class A{
	public:
		void f1(){}
	protected:
		void f2(){}
	private:
		int i;
};
class B: public A{
	public:
		void f3(){}
		int k;
	private:
		int m;
};
class C: protected B{
	public:
		void f4(){}
	protected:
		int m;
	private:
		int n;
};
class D: private C{
	public:
		void f5(){}
	protected:
		int p;
	private:
		int q;
};
int main(){
	A a1;			// a1 是基类A的对象
	B b1;			// b2 是派生类B的对象
	C c1;			// c3 是派生类C的对象
	D d1;			// d1 是派生类D的对象
	return 0;
}

回答:

2.1 基类和派生类内部的访问权限

首先分析各类的成员访问权限:

1)A类:

  • 公有成员函数:f1()
  • 保护成员函数:f2()
  • 私有数据成员:i

2)B类:

  • 公有成员函数:f3()
  • 公有数据成员:k
  • 私有数据成员:m
  • 继承自类A的公有成员函数:f1()(因公有继承,保持为公有)
  • 继承自类A的保护成员函数:f2()(因公有继承,保持为保护)
  • 继承自类A的私有数据成员:i(在派生类B中不可见)

3)C类:

  • 公有成员函数:f4()
  • 保护数据成员:m
  • 私有数据成员:n
  • 继承自类B的公有成员函数:f3()(因保护继承,B类中继承的公有成员函数变有保护成员)
  • 继承自类B的公有数据成员:k(因保护继承,B类中继承的公有数据成员变为保护成员)
  • 继承自类B的私有数据成员:m(在派生类C中不可见)
  • 继承自类A的公有成员函数:f1()(因保护继承,A类中继承的公有成员函数变有保护成员)
  • 继承自类A的保护成员函数:f2()(因保护继承,A类中继承的公有数据成员变为保护成员)
  • 继承自类A的私有数据成员:i(在派生类C中不可见)

4)D类:

  • 公有成员函数:f5()
  • 保护数据成员:p
  • 私有数据成员:q
  • 继承自类C的公有成员函数:f4()(因私有继承,在类外部不可见)
  • 继承自类C的保护数据成员:m(因私有继承,在类外部不可见)
  • 继承自类A的保护成员函数:f1()和f2()(因在类C中为保护继承,故类C继承了类A中的公有成员在类C中变为保护成员)
  • 继承自类B保护成员:f3()和k(因在类C中为保护继承,故类C继承了类B中的公有成员在类C中变成保护成员)

2.2 基类和派生类外部的访问权限

        在main方法中,创建A、B、C、D类的对象a1、b1、c1、d1。

1)对象a1:

  • 可以调用公有成员函数:f1()
  • 保护成员函数f2()和私有成员i在类外部无法访问。

2)对象b1:

  • 可以调用公用成员函数:f2()
  • 可以调用公有数据成员:k
  • 可以调用继承类A中公有成员函数:f1()

3)对象c1:

  • 可以调用公有成员函数:f4()
  • 保护数据成员m和私有数据成员n在类外无法调用
  • 由于类C保护继承类B,故类A和类B中公有成员和保护成员被类C继承后变为保护成员,所以在类外无法访问。

4)对象d1:

  • 可以调用公有成员函数:f5()
  • 保护数据成员p和私有数据成员q在类外无法调用
  • 由于类D为私有继承,侧被继承成员类外无法调用

三、基类和派生类的构造函数

问题:分析以下代码,查看运行后输出结果,是否运行正确,以及执行过程中调用构造函数执行过程。

#include <iostream>
using namespace std;

class A{
	public:
		A(){
			a = 0;
			b = 0;
		}
		A(int i){
			a = i;
			b = 0;
		}
		A(int i, int j){
			a = i;
			b = j;
		}
		void display(){
			cout <<"a=" <<a <<" b=" <<b;
		}
	private:
		int a;
		int b;
};
class B: public A{
	public:
		B(){
			c = 0;
		}
		B(int i): A(i){
			c = 0;
		}
		B(int i, int j): A(i, j){
			c = 0;
		}
		B(int i, int j, int k): A(i, j), c(k){
		}
		void display1(){
			display();
			cout <<" c=" <<c <<endl;
		}
	private:
		int c;
};

int main(){
	B b1;
	B b2(2);
	B b3(2, 3);
	B b4(2, 3, 5);
	b1.display1();
	b2.display1();
	b3.display1();
	b4.display1();
	return 0;
}

回答:

1)运行后程序正确,结果如下图:

2)调用构造函数执行过程

  • 创建b1对象时,首先调用类B的默认构造函数,先执行继承类A中的默认构造函数初始化数据成员,再初始化自己的数据成员。
  • 创建b2对象时,先执行继承类A中构造函数A(int i)进行初始化,再初始化自己的数据成员。
  • 创建b3对象时,先执行继承类A中构造函数A(int i, int j)进行初始化,再初始化自己的数据成员。
  • 创建b4对象时,先执行继承类A中构造函数A(int i, int j)进行初始化,再初始化自己的数据成员。

        综上所述,可见被继承的基类构造函数先执行初始化,再初始化派生类自己的成员。可以将上述代码添加输出,更直观了解其执行过程。代码如下:

#include <iostream>
using namespace std;

class A{
	public:
		A(){
			a = 0;
			b = 0;
			cout <<"A default" <<endl;
		}
		A(int i){
			a = i;
			b = 0;
			cout <<"A i" <<endl;
		}
		A(int i, int j){
			a = i;
			b = j;
			cout <<"A i,j" <<endl;
		}
		void display(){
			cout <<"a=" <<a <<" b=" <<b;
		}
	private:
		int a;
		int b;
};
class B: public A{
	public:
		B(){
			c = 0;
			cout <<"B default" <<endl;
		}
		B(int i): A(i){
			c = 0;
			cout <<"B i" <<endl;
		}
		B(int i, int j): A(i, j){
			c = 0;
			cout <<"B i, j" <<endl;
		}
		B(int i, int j, int k): A(i, j), c(k){
			cout <<"B i,j,k" <<endl;
		}
		void display1(){
			display();
			cout <<" c=" <<c <<endl;
		}
	private:
		int c;
};

int main(){
	B b1;
	B b2(2);
	B b3(2, 3);
	B b4(2, 3, 5);
	b1.display1();
	b2.display1();
	b3.display1();
	b4.display1();
	return 0;
}

        运行结果如下图:

四、基类和派生类的析构函数

问题:阅读以下程序,写出运行时输出的结果,并分析程序执行过程中,调用的构造函数和析构函数的过程。

#include <iostream>
using namespace std;
class A{
	public:
		A(){
			cout <<"constructing A" <<endl;
		}
		~A(){
			cout <<"destructing A" <<endl;
		}
};
class B: public A{
	public:
		B(){
			cout <<"constructing B" <<endl;
		}
		~B(){
			cout <<"destructing B" <<endl;
		}
};
class C: public B{
	public:
		C(){
			cout <<"constructing C" <<endl;
		}
		~C(){
			cout <<"destructing C" <<endl;
		}
};
int main(){
	C c1;
	return 0;
}

回答:

1)运行程序正确,结果如下图:

2)调用构造函数和析构函数的过程

        构造函数执行过程:当创建C c1对象时,由于C类继承B类,B类继承A类,因此会先调用基类A的构造函数进行初始化,再调用B类的构造函数进行初始化,最后再调用自身进行初始化成员。所以构造函数输出结果为:constructing A,constructing B,constructing C。

        析构函数执行过程:析构函数的销毁过程刚好与构造函数的过程相反,所以会先调用类C的析函数,再调用类B的析构函数,最后再调用类A的析构函数。所以析构函数输出结果为:destructing C,destructing B,destructing A。

五、多继承

问题:分别定义Teacher(教师)类和Cadre(干部)类,采用多重继承方式由这两个类派生出新类Teacher_Cadre(教师兼干部)。

  1. 在两个基类中都包含姓名、年龄、性别、地址、电话等数据成员。
  2. 在Teacher类中还包含数据成员title(职称)、在Cadre类中还包含数据成员post(职务),在Teacher_Cadre类中还包含数据成员wages(工资)。
  3. 对两个基类中的姓名、年龄、性别、地址、电话等数据成员用的名字,在引用这些数据成员时,指定作用域。
  4. 在类体中声明成员函数,在类外定义成员函数。
  5. 在派生类Teacher_Cadre类的成员函数show中调用Teacher类中的display函数,输出姓名、年龄、性别、职称、地址、电话,然后再用cout语句输出职务与工资。

回答:代码如下:

#include <iostream>
class Teacher{
	private:
		std::string name;
		int age;
		char gender;
		std::string address;
		std::string phone;
		std::string title;				//职称
	public:
		Teacher(std::string name, int age, char gender, std::string address, std::string phone, std::string title):
			name(name), age(age), gender(gender), address(address), phone(phone), title(title){}
		void display();
};
class Gadre{
	private:
		std::string name;
		int age;
		char gender;
		std::string address;
		std::string phone;
		std::string post;				//职务
	public:
		Gadre(std::string name, int age, char gender, std::string address, std::string phone, std::string post):
			name(name), age(age), gender(gender), address(address), phone(phone), post(post){}
		std::string get_post();
};
class Teacher_Gadre: public Teacher, public Gadre{
	private:
		double wages;			//工资
	public:
		Teacher_Gadre(std::string name, int age, char gender, std::string address, std::string phone, 
					  std::string title, std::string post, double wages):
			Teacher(name, age, gender, address, phone, title), Gadre(name, age, gender, address, phone, post), wages(wages){}
		void show();
};
// 类体外定义Teacher类的display成员函数
void Teacher::display(){
	std::cout <<"name:" <<name <<", age:" <<age <<", gender:" <<gender <<", address:" <<address 
					  <<", phone:" <<phone <<", title:" <<title <<std::endl;
}
// 类体外定义Gadre类的get_post成员函数
std::string Gadre::get_post(){
	return post;
}
// 类体外定义show函数
void Teacher_Gadre::show(){
	display();
	std::cout <<"Post:" <<get_post() <<", Wage:" <<wages <<std::endl;
}
int main(){
	// 创建对象tc并初始化数据
	Teacher_Gadre tc("John", 30, 'M', "345 Main St", "13288889999", "Professor", "History", 5000);
	// 调用show()函数显示结果
	tc.show();
	return 0;
}

运行结果如下图:

六、继承与组合

        这里再复习下在上一篇中讲到的“五、继承与组合”,地址:C++面向对象程序设计 - 多继承,以及基类与派生类转换-CSDN博客

问题:将其中代码再完善一下,通过定义Student对象s给出所有数据的初值,再修改对象s的生日数据,最后输出对象s的全部最新数据。

回答:代码如下:

#include <iostream>
#include <string>
using namespace std;
class Person{
	protected:
		string name;
		int age;
	public:
		Person(string name, int age): name(name), age(age){}
};
// 定义生日类
class Birthday{
	private:
		int year;
		int month;
		int day;
	public:
		Birthday(int year, int month, int day): year(year), month(month), day(day){}
		// 声明修改数据成员函数
		void reset(int, int, int);
		// 显示日期
		void show(){
			cout <<year <<'/' <<month <<'/' <<day <<endl;
		}
};
// 类体外定义重置生日函数
void Birthday::reset(int year, int month, int day){
	this->year = year;
	this->month = month;
	this->day = day;
}
// Person作为Student基类
class Student: public Person{
	protected:
		Birthday birth;
	public:
		// 构造函数
		Student(string name, int age, Birthday birth): Person(name, age), birth(birth){}
		// 声明reset()成员函数修改生日(由于birth对象作用数据成员,故公有成员函数reset()是无法继承的)
		void reset(int, int, int);
		// 显示结果
		void display(){
			cout <<"name:" <<name <<endl;
			cout <<"age:" <<age <<endl;
			cout <<"birth:"; birth.show();
		}
};
// 类体外定义重置生日函数
void Student::reset(int year, int month, int day){
	birth.reset(year, month, day);
}
int main(){
	Student s("Tom", 20, Birthday(2000, 1, 15));
	// 调用公有函数reset()修改生日
	s.reset(2024, 5, 6);
	// 显示信息
	s.display();
	return 0;
}

        运行结果如下:

        由于Birthday类为Student类的保护成员,类Student并未继承类Birthday,故类Birthday中公有成员函数reset()是无法通过对象s访问的;对象birth是对象s的保护成员,故在s对象内部可以访问birth.reset()的,所以需要在类Student中再定义一个成员函数用于修改生日的功能。

        由于对象birth为保护成员,只能在类内部访问,那是否还有其他方法可以修改生日呢?当然可以的,前面大家学习到的友函数,是可以访问类中的私有和保护成员。修改后代码如下:

#include <iostream>
#include <string>
using namespace std;
class Person{
	protected:
		string name;
		int age;
	public:
		Person(string name, int age): name(name), age(age){}
};
// 定义生日类
class Birthday{
	private:
		int year;
		int month;
		int day;
	public:
		Birthday(int year, int month, int day): year(year), month(month), day(day){}
		// 声明修改数据成员函数
		void reset(int, int, int);
		// 显示日期
		void show(){
			cout <<year <<'/' <<month <<'/' <<day <<endl;
		}
};
// 类体外定义重置生日函数
void Birthday::reset(int year, int month, int day){
	this->year = year;
	this->month = month;
	this->day = day;
}
// Person作为Student基类
class Student: public Person{
	protected:
		Birthday birth;
	public:
		// 构造函数
		Student(string name, int age, Birthday birth): Person(name, age), birth(birth){}
		// 声明Student类的友函数
		friend void reset_birth(Student&, int, int, int);
		// 显示结果
		void display(){
			cout <<"name:" <<name <<endl;
			cout <<"age:" <<age <<endl;
			cout <<"birth:"; birth.show();
		}
};
// 定义Student类的友函数
void reset_birth(Student& s, int year, int month, int day){
	s.birth.reset(year, month, day);
}
int main(){
	Student s("Tom", 20, Birthday(2000, 1, 15));
	// 调用Student的友函数修改生日
	reset_birth(s, 2024, 5, 6);
	// 显示信息
	s.display();
	return 0;
}

        运行结果还是一样的,结果如下图:

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

分布式与一致性协议之ZAB协议(四)

ZAB协议 ZooKeeper是如何选举领导者的。 首先我们来看看ZooKeeper是如何实现成员身份的&#xff1f; 在ZooKeeper中&#xff0c;成员状态是在QuorumPeer.java中实现的&#xff0c;为枚举型变量 public enum ServerState { LOOKING, FOLLOWING, LEADING, OBSERVING }其实&…

权益商城系统源码 现支持多种支付方式

简介&#xff1a; 权益商城系统源码&#xff0c;支持多种支付方式&#xff0c;后台商品管理&#xff0c;订单管理&#xff0c;串货管理&#xff0c;分站管理&#xff0c;会员列表&#xff0c;分销日志&#xff0c;应用配置。 上传到服务器&#xff0c;修改数据库信息&#xff…

AI预测福彩3D第10套算法实战化赚米验证第2弹2024年5月6日第2次测试

由于今天白天事情比较多&#xff0c;回来比较晚了&#xff0c;趁着还未开奖&#xff0c;赶紧把预测结果发出来吧~今天是第2次测试~ 2024年5月6日福彩3D预测结果 6-7码定位方案如下&#xff1a; 百位&#xff1a;3、4、1、7、8、9 十位&#xff1a;4、5、3、7、8、9 个位&#x…

【数据结构(邓俊辉)学习笔记】栈与队列01——栈接口与应用

文章目录 0. 概述1. 操作与接口2. 操作实例3. 实现4. 栈与递归5. 应用5.1 逆序输出5.1.1 进制转换5.1.1.1 思路5.1.1.2 算法实现 5.2 递归嵌套5.2.1 栈混洗5.2.1.1 混洗5.2.1.2 计数5.2.1.3 甄别 5.2.2 括号匹配5.2.2.1 构思5.2.2.2 实现5.2.2.3 实例 5.3 延迟缓冲5.3.1 中缀表…

华为ensp中USG6000V防火墙双机热备VRRP+HRP原理及配置

作者主页&#xff1a;点击&#xff01; ENSP专栏&#xff1a;点击&#xff01; 创作时间&#xff1a;2024年5月6日20点26分 华为防火墙双机热备是一种高可用性解决方案&#xff0c;可以将两台防火墙设备组成一个双机热备组&#xff0c;实现主备切换。当主用防火墙出现故障时&…

企业网站 | 被攻击时该怎么办?

前言 每天&#xff0c;数以千计的网站被黑客入侵。发生这种情况时&#xff0c;被入侵网站可用于从网络钓鱼页面到SEO垃圾邮件或者其它内容。如果您拥有一个小型网站&#xff0c;很容易相信黑客不会对它感兴趣。不幸的是&#xff0c;通常情况并非如此。 黑客入侵网站的动机与所…

书籍推荐|经典书籍ic书籍REUSE METHODOLOGY MANUALFOR等和verilog网站推荐(附下载)

大家好&#xff0c;今天是51过后的第一个工作日&#xff0c;想必大家都还没有完全从节假日的吃喝玩乐模式转变为勤勤恳恳的打工人模式&#xff0c;当然也包括我&#xff0c;因此这次更新主要是分享几篇书籍和verilog相关的学习网站~ 首先是一本数字电路相关的基础书籍&#xf…

深入理解Docker容器镜像

深入理解Docker容器镜像 1 容器是什么&#xff1a;特殊的进程 容器其实是一种沙盒技术。顾名思义&#xff0c;沙盒就是能够像一个集装箱一样&#xff0c;把你的应用“装”起来的技术。这样&#xff0c;应用与应用之间&#xff0c;就因为有了边界而不至于相互干扰&#xff1b;而…

流量分析。

流量分析 在Wireshak抓包可以看到正常的执行流程如下&#xff1a; ● Client向Server发起Load data local infile请求 ● Server返回需要读取的文件路径 ● Client读取文件内容并发送给Server ● PS&#xff1a;在本机上启动服务端与客户端&#xff0c;启动wireshark 抓包&…

navicat 连接 阿里云 RDS mysql 数据库

首先上官方教程连接 下面是我的实操记录 1、先输入正确的账号、密码 2、再加上数据库名称

省公派出国|社科类普通高校教师限期内赴英国访学交流

在国外访问学者申请中&#xff0c;人文社科类相对难度更大&#xff0c;尤其是英语语言学&#xff0c;作为非母语研究并不被国外高校看重。经过努力&#xff0c;最终我们帮助Z老师申请到英国坎特伯雷基督教会大学的访学职位&#xff0c;并在限期内出国。 Z老师背景&#xff1a; …

Chrome浏览器安装React工具

一、如果网络能访问Google商店&#xff0c;直接安装官方插件即可 二、网络不能访问Google商店&#xff0c;使用安装包进行安装 1、下载react工具包 链接&#xff1a;https://pan.baidu.com/s/1qAeqxSafOiNV4CG3FVVtTQ 提取码&#xff1a;vgwj 2、chrome浏览器安装react工具…

io (fscanf fprintf)

20 #include <sys/un.h>21 typedef struct stu22 {23 char name[16];24 int age;25 double score;26 }stu;27 int main(int argc, const char *argv[])28 {29 /* 有如下结构体30 31 申请该结构体数组&#xff0c;容量为5&#xff0c;初始化5个学生的信息32 …

C++:何为,。。。。。。

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

new mars3d.control.MapSplit({实现点击卷帘两侧添加不同图层弹出不同的popup

new mars3d.control.MapSplit({实现点击卷帘两侧添加不同图层弹出不同的popup效果&#xff1a; 左侧&#xff1a; 右侧&#xff1a; 说明&#xff1a;mars3d的3.7.12以上版本才支持该效果。 示例链接&#xff1a; 功能示例(Vue版) | Mars3D三维可视化平台 | 火星科技 相关代…

【6D位姿估计】ZebraPose 层次化分组策略 由粗到细的表面编码

前言 本文介绍6D位姿估计的方法ZebraPose&#xff0c;也可以称为六自由度物体姿态估计&#xff0c;输入单张图片&#xff0c;输出物体的三维位置和三维方向。 它来自CVPR2022的论文&#xff0c;通过层次化分组策略&#xff0c;高效地编码物体表面的信息。 ZebraPose提出了一…

基于Springboot的家具网站

基于SpringbootVue的家具网站设计与实现 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringbootMybatis工具&#xff1a;IDEA、Maven、Navicat 系统展示 用户登录 首页 商家 家具信息 家居资讯 后台管理 后台首页 用户管理 商家管理 家具类型管理 家具…

《Python编程从入门到实践》day20

#尝试在python3.11文件夹和pycharm中site-packages文件夹中安装&#xff0c;最终在scripts文件夹中新建py文件成功导入pygame运行程序 #今日知识点学习 import sysimport pygameclass AlienInvasion:"""管理游戏资源和行为的类"""def __init__(…

Python从0到100(二十):文件读写和文件操作

一、文件的打开和关闭 有了文件系统可以非常方便的通过文件来读写数据&#xff1b;在Python中要实现文件操作是非常简单的。我们可以使用Python内置的open函数来打开文件&#xff0c;在使用open函数时&#xff0c;我们可以通过函数的参数指定文件名、操作模式和字符编码等信息…

websevere服务器从零搭建到上线(四)|muduo网络库的基本原理和使用

文章目录 muduo源码编译安装muduo框架讲解muduo库编写服务器代码示例代码解析用户连接的创建和断开回调函数用户读写事件回调 使用vscode编译程序配置c_cpp_properties.json配置tasks.json配置launch.json编译 总结 muduo源码编译安装 muduo依赖Boost库&#xff0c;所以我们应…