【C++】---多态

【C++】---多态

  • 一、多态的概念
  • 二、多态的定义及实现
    • 1、构成多态的2个必要条件
    • 2、什么叫做虚函数的重写?
    • 3、虚函数重写的3个例外
    • 4、建议把 析构函数 都定义为:虚函数
  • 三、C++11的两个关键字:final override
    • 1、final:修饰虚函数,表示该虚函数不能再被重写
    • 2、override: 检查是否重写
  • 四、重载、隐藏、重写 的比较
  • 五、多态的原理
    • 1、虚表(虚函数表)
    • 2、虚表指针:
    • 3、底层原理:满足多态后,在调用的指令中,指向谁 就去谁的虚表 里面 找对应的 虚函数 进行调用!
  • 六、抽象类
    • 1、纯虚函数
    • 2、抽象类(接口类)
    • 3、接口继承和实现继承
  • 七、单继承关系中的虚函数表
    • 1、单继承中的虚函数表
  • 八、继承和多态常见的面试问题
    • 1、选择题
    • 2、问答题

一、多态的概念

多态就是:多种形态。通俗的来说,多态的概念就是:同一件事情,不同的对象去做会有不同的结果。

二、多态的定义及实现

1、构成多态的2个必要条件

1. 子类必须对父类的虚函数进行重写(重写,包括三同:返回值相同,函数名相同,参数列表相同。协变除外)
2. 必须是父类的指针或者引用去调用虚函数,而且被调用的函数必须是虚函数。

2、什么叫做虚函数的重写?

1、什么叫做虚函数?

虚函数:在 成员函数 前面加 virtual

2、虚函数的重写(覆盖):派生类中有一个跟基类完全相同的虚函数(即派生类虚函数与基类虚函数的返回值类型、函数名字、参数列表完全相同),称子类的虚函数重写了基类的虚函数。

#include<iostream>
using namespace std;class Person
{
public:virtual void Buy_ticket(){cout << "成人-全价" << endl;}
};class Student : public Person
{
public:virtual void Buy_ticket(){cout << "学生-半价" << endl;}
};void Func(Person& p)
{p.Buy_ticket();
}int main()
{Person p1;Student s1;Func(p1);Func(s1);return 0;
}

在这里插入图片描述

3、虚函数重写的3个例外

  1. 协变:基类 与 派生类 虚函数返回值类型 可以不同。派生类重写基类虚函数时,与基类虚函数返回值类型不同。即基类虚函数返回基类对象的指针或者引用,派生类虚函数返回派生类对象的指针或者引用时,称为协变。(了解)

协变 的代码

class A{};
class B : public A {};
class Person {
public:virtual A* f() {return new A;}
};
class Student : public Person {
public:virtual B* f() {return new B;}
};
  1. 子类的虚函数可以不写:virtual (因为形成多态后,如果存在调用子类的虚函数,实际上,只看子类虚函数的内部函数实现,不看头部,头部继承的父类,所以:子类虚函数可以不写:virtual)
    但是该种写法不是很规范,不建议这样使用

在这里插入图片描述

3、子类的虚函数中:析构函数,即使函数名不同,也会构成:重写!

解释:

如果基类的析构函数为虚函数,此时派生类析构函数只要定义,无论是否加virtual关键字,

都与基类的析构函数构成重写,虽然基类与派生类析构函数名字不同。虽然函数名不相同,

看起来违背了重写的规则,其实不然,这里可以理解为编译器对析构函数的名称做了特殊
处理,编译后析构函数的名称统一处理成destructor!!!

class Person {
public:virtual ~Person() {cout << "~Person()" << endl;}
};
class Student : public Person {
public:virtual ~Student() { cout << "~Student()" << endl; }
};
// 只有派生类Student的析构函数重写了Person的析构函数,下面的delete对象调用析构函
数,才能构成多态,才能保证p1和p2指向的对象正确的调用析构函数。
int main()
{Person* p1 = new Person;Person* p2 = new Student;delete p1;delete p2;return 0;
}

4、建议把 析构函数 都定义为:虚函数

注意:如果不把析构函数都定义为虚函数的话,可能会发生内存泄漏!

1、自己好好想为什么建议把析构函数定义虚函数,防止发生内存泄漏?

因为如果所有的析构函数都定义为虚函数之后,它们所有的析构函数就会形成多态的关系,形成多态之后,就会达到我们的期望:delete的时候,子类对象调用子类的析构函数,父类对象要用父类的析构函数

如果在子类里面定义一个私有成员变量,如果所有析构函数不写成虚函数,无法满足多态的条件,没有形成多态的话,像上面子类有一个私成员变量,这个私有成员变量,无法被释放掉,就会导致内存泄漏。

在这里插入图片描述

三、C++11的两个关键字:final override

1、final:修饰虚函数,表示该虚函数不能再被重写

class Car
{
public:virtual void Drive() final {}
};
class Benz :public Car
{
public:virtual void Drive() {cout << "Benz-舒适" << endl;}
};

2、override: 检查是否重写

class Car{
public:virtual void Drive(){}
};
class Benz :public Car {
public:virtual void Drive() override {cout << "Benz-舒适" << endl;}
};

四、重载、隐藏、重写 的比较

在这里插入图片描述

五、多态的原理

1、虚表(虚函数表)

// 这里常考一道笔试题:sizeof(Base)是多少?
class Base
{
public:virtual void Func1(){cout << "Func1()" << endl;}
private:int _b = 1;
};

在这里插入图片描述

// 针对上面的代码我们做出以下改造
// 1.我们增加一个派生类Derive去继承Base
// 2.Derive中重写Func1
// 3.Base再增加一个虚函数Func2和一个普通函数Func3
class Base
{
public:virtual void Func1(){cout << "Base::Func1()" << endl;}virtual void Func2(){cout << "Base::Func2()" << endl;}void Func3(){cout << "Base::Func3()" << endl;}
private:int _b = 1;
};
class Derive : public Base
{
public:virtual void Func1(){
cout << "Derive::Func1()" << endl;}
private:int _d = 2;
};
int main()
{Base b;Derive d;return 0;
}

在这里插入图片描述

  • 虚表:存在于哪里?常量区
  • 虚函数:和普通函数一样,存在代码段!
  • 虚函数指针:存在于:虚表

2、虚表指针:

虚表指针:
① 只要类里面有虚函数,就一定有虚表指针!
②同类型的对象,共用一张虚表

在这里插入图片描述

3、底层原理:满足多态后,在调用的指令中,指向谁 就去谁的虚表 里面 找对应的 虚函数 进行调用!

上面分析了这个半天了那么多态的原理到底是什么?还记得这里Func函数传Person调用的
Person::BuyTicket,传Student调用的是Student::BuyTicket

在这里插入图片描述
①满足多态后,在调用的指令中,指向谁 就去谁的虚表 里面 找对应的 虚函数 进行调用!
②如果函数不满足多态,那么就与指向的对象没有关系,跟你函数的形参类型有关系。
不满足多态,在编译链接时就直接,确定好调用函数的类型,地址!

在这里插入图片描述

六、抽象类

1、纯虚函数

定义:在虚函数的后面写上 =0

2、抽象类(接口类)

定义:包含纯虚函数的类

性质:抽象类不能实例化出对象。子类继承抽象类后也不能实例化出对象,只有重写纯虚函数,子类才能实例化出对象。

意义:

① 能够更好地去表示现实世界中没有实例对象是我抽象类型,如:植物、人、动物

② 体现接口继承,强制子类去重写虚函数(就算不重写,子类也是抽象类)

class Car
{
public:virtual void Drive() = 0;
};
class Benz :public Car
{
public:virtual void Drive(){cout << "Benz-舒适" << endl;}
};
class BMW :public Car
{
public:virtual void Drive(){cout << "BMW-操控" << endl;}
};
void Test()
{Car* pBenz = new Benz;pBenz->Drive();Car* pBMW = new BMW;pBMW->Drive();
}

抽象类不能实例化出对象:

int main()
{Animal a;return 0;
}

3、接口继承和实现继承

普通函数的继承是一种实现继承,派生类继承了基类函数,可以使用函数,继承的是函数的实现。
虚函数的继承是一种接口继承,派生类继承的是基类虚函数的接口,目的是为了重写,达成多态,继承的是接口。所以如果不实现多态,不要把函数定义成虚函数。

七、单继承关系中的虚函数表

1、单继承中的虚函数表

class Base { 
public :virtual void func1() { cout<<"Base::func1" <<endl;}virtual void func2() {cout<<"Base::func2" <<endl;}
private :int a;
};
class Derive :public Base { 
public :virtual void func1() {cout<<"Derive::func1" <<endl;}virtual void func3() {cout<<"Derive::func3" <<endl;}virtual void func4() {cout<<"Derive::func4" <<endl;}
private :int b;
};

在这里插入图片描述
在这里插入图片描述

八、继承和多态常见的面试问题

1、选择题

  1. 下面哪种面向对象的方法可以让你变得富有( )
    A: 继承 B: 封装 C: 多态 D: 抽象

答案: A 当然是继承更富有啦

  1. ( )是面向对象程序设计语言中的一种机制。这种机制实现了方法的定义与具体的对象无关,而对方法的调用则可以关联于具体的对象。
    A: 继承 B: 模板 C: 对象的自身引用 D: 动态绑定

答案: D 动态绑定是函数调用时关联到具体对象

  1. 面向对象设计中的继承和组合,下面说法错误的是?()
    A:继承允许我们覆盖重写父类的实现细节,父类的实现对于子类是可见的,是一种静态复用,也称为白盒复用
    B:组合的对象不需要关心各自的实现细节,之间的关系是在运行时候才确定的,是一种动态复用,也称为黑盒复用
    C:优先使用继承,而不是组合,是面向对象设计的第二原则
    D:继承可以使子类能自动继承父类的接口,但在设计模式中认为这是一种破坏了父类的封装性的表现

答案: C 尽量少用继承,会破坏封装原则,多用组合,能降低耦合度

  1. 以下关于纯虚函数的说法,正确的是( )
    A:声明纯虚函数的类不能实例化对象 B:声明纯虚函数的类是虚基类
    C:子类必须实现基类的纯虚函数 D:纯虚函数必须是空函数

答案: A 包含纯虚函数的类叫做抽象类,抽象类不能实例化出对象

  1. 关于虚函数的描述正确的是( )
    A:派生类的虚函数与基类的虚函数具有不同的参数个数和类型 B:内联函数不能是虚函数
    C:派生类必须重新定义基类的虚函数 D:虚函数可以是一个static型的函数

答案: B inline函数没有地址,当inline成为虚函数后,虚表里面要放它的地址,构成多态时,根据虚函数表指针去call这个地址,就不能展开了,就忽略了内联属性,加了虚函数以后就不再是内联函数了。

  1. 关于虚表说法正确的是( )
    A:一个类只能有一张虚表
    B:基类中有虚函数,如果子类中没有重写基类的虚函数,此时子类与基类共用同一张虚表
    C:虚表是在运行期间动态生成的
    D:一个类的不同对象共享该类的虚表

对于A如果是多继承,那么这个类的对象会有多张虚表

对于B,监视:

#include<iostream>
using namespace std;class Animal
{
public:virtual void Color()//颜色{cout << "virtual Animal::color" << endl;}virtual void Name()//名称{cout << "virtual Animal::name" << endl;}
};class Coral :public Animal
{};int main()
{Animal a;Coral c;return 0;
}

发现虚表指针不同,虽然虚表指针中存放的虚函数地址相同:

在这里插入图片描述
对于C:虚表在编译时就已经生成了

对于D:

#define  _CRT_SECURE_NO_WARNINGS  1
#include<iostream>
using namespace std;class Animal
{
public:virtual void Color()//颜色{cout << "virtual Animal::color" << endl;}virtual void Name()//名称{cout << "virtual Animal::name" << endl;}
};int main()
{Animal a;Animal a1;return 0;
}

监视发现:a和a1的虚表指针地址相同,虚表指针中存放的虚函数地址也相同

在这里插入图片描述

  1. 假设A类中有虚函数,B继承自A,B重写A中的虚函数,也没有定义任何虚函数,正确的是()
    A:A类对象的前4个字节存储虚表地址,B类对象前4个字节不是虚表地址
    B:A类对象和B类对象前4个字节存储的都是虚基表的地址
    C:A类对象和B类对象前4个字节存储的虚表地址相同
    D:A类和B类中的内容完全一样,但是A类和B类使用的不是同一张虚表

接下来是我对这一题的查缺补漏。一个选项一个选项,详细的解析一下

A、对于a选项来说,只要一个类里面有虚函数,这个类的内存里前4个字节都储存的是虚表的地址

B、 b选项和a选项是一样的。

C、关于这个虚表地址相同与否,可有的说了!

①:虽然现在有两个不同的类,但是如果子类没有对父类的虚函数进行重写行为,那么子类和父类 可能 共用一张虚表。
②:与①对立如果两个不同的类子类对父类的虚函数进行了重写行为,那么两者就用各自的去表。(因为这样就会构成多态,如果构成多态,调用谁,就去自己的虚表里面,找自己的虚函数地址)

答案:D 因为题目中已经说了子类对父类的虚函数进行了重写,所以说两者用的是各自的虚表。

  1. 下面程序输出结果是什么? ()
#include<iostream>using namespace std;
class A{
public:A(char *s) { cout<<s<<endl; }~A(){}
};
class B:virtual public A
{
public:B(char *s1,char*s2):A(s1) { cout<<s2<<endl; }
};
class C:virtual public A
{
public:C(char *s1,char*s2):A(s1) { cout<<s2<<endl; }
};
class D:public B,public C
{
public:D(char *s1,char *s2,char *s3,char *s4):B(s1,s2),C(s1,s3),A(s1){ cout<<s4<<endl;}
};
int main() {D *p=new D("class A","class B","class C","class D");delete p;return 0;
}

A:class A class B class C class D B:class D class B class C class A
C:class D class C class B class A D:class A class C class B class D

答案:A 子类构造函数必须调用父类的构造函数初始化父类的成员,因此执行D的构造函数前必须执行B和C的构造函数,执行B和C的构造函数前必须执行A的构造函数

  1. 多继承中指针偏移问题?下面说法正确的是( )
class Base1 {  public:  int _b1; };
class Base2 {  public:  int _b2; };
class Derive : public Base1, public Base2 { public: int _d; };
int main(){Derive d;Base1* p1 = &d;Base2* p2 = &d;Derive* p3 = &d;return 0;
}

A:p1 == p2 == p3 B:p1 < p2 < p3 C:p1 == p3 != p2 D:p1 != p2 != p3

在这里插入图片描述
10. 以下程序输出结果是什么()

class A{public:virtual void func(int val = 1){ std::cout<<"A->"<< val <<std::endl;}
virtual void test(){ func();}};class B : public A{public:void func(int val=0){ std::cout<<"B->"<< val <<std::endl; }};int main(int argc ,char* argv[]){B*p = new B;p->test();return 0;}

A: A->0 B: B->1 C: A->1 D: B->0 E: 编译出错 F: 以上都不正确

这里考察的一个点就是:虚函数重写,重写的是函数体实现,但函数结构部分(virtual 返回值 函数名 参数列表)用的还是父类的。
这就是为什么第3个例外:子类的虚函数可以不加virtual,因为他压根就不看子类前面的函数结构,他用是父类结构(virtual 返回值 函数名 参数列表)。

在这里插入图片描述

2、问答题

  1. 什么是多态?(不同的对象去完成同一件事情,产生了不同的结果)

  2. 多态的原理?(一句话:形成多态之后,指向谁,就去谁的虚表里面找对应的虚函数地址进行调用对应的虚函数。)
    当指针或引用指向父类对象时,调用的就是父类的虚表中的虚函数,当指针或引用指向子类对象时,调用的就是子类虚表中的虚函数。

  3. inline函数可以是虚函数吗?

答:不能,因为inline函数没有地址,无法把地址放到虚函数表中。

inline函数没有地址,当inline成为虚函数后,虚表里面要放它的地址,构成多态时,根据虚函数表指针去call这个地址,就不能展开了,就忽略了内联属性,加了虚函数以后就不再是内联函数了。

  1. 静态成员可以是虚函数吗?

答:不能,因为静态成员函数没有this指针,使用类型::成员函数的调用方式无法访问虚函数表,所以静态成员函数无法放进虚函数表。

  1. 构造函数可以是虚函数吗?

答:不能,因为对象中的虚函数表指针是在构造函数初始化列表阶段才初始化的。

假如构造函数是虚函数:

①调用构造函数虚函数必须要去虚表里面找,这就要求对象必须已经被初始化出来了。

②要初始化对象,就要调构造函数虚函数,但是对象还没有构造出来,虚表还没有初始化,还找不到构造函数虚函数地址。

这就陷入了死循环

  1. 析构函数可以是虚函数吗?什么场景下析构函数是虚函数?

答:可以,最好把基类的析构函数定义成虚函数。

  1. 对象访问普通函数快还是虚函数更快?

答:

如果是普通对象,那么访问普通函数和虚函数是一样快的。

如果是指针对象或者是引用对象,则调用的普通函数快,因为构成多态,运行时调用虚函数需要到虚函数表中去查找,需要耗时。

  1. 虚函数表是在什么阶段生成的,存在哪的?

答:虚函数表是在编译阶段就生成的,一般情况下存在代码段(常量区)的。

  1. C++菱形继承的问题?虚继承的原理?

答:子类对象会有两份父类的成员,菱形继承会导致数据冗余和二义性。

虚继承通过虚基表指针的偏移量计算出父类成员的起始地址,这样就只需要在内存中存一份父类成员,解决了数据冗余和二义性的问题。

  1. 什么是抽象类?抽象类的作用?

答:包含纯虚函数的类叫做抽象类。

抽象类不能实例化出对象。子类继承抽象类后也是抽象类,没有重写虚函数,不能实例化出对象,只有重写纯虚函数,子类才能实例化出对象。

① 能够更好地去表示现实世界中没有实例对象是我抽象类型,如:植物、人、动物

② 体现接口继承,强制子类去重写虚函数(就算不重写,子类也是抽象类)


好了,今天的分享就到这里了
如果对你有帮助,记得点赞👍+关注哦!
我的主页还有其他文章,欢迎学习指点。关注我,让我们一起学习,一起成长吧!
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring—Spring配置文件概念及应用(实现一个图形验证码)

文章目录 配置文件配置文件作用配置文件的格式配置文件优先级说明配置文件书写代码的格式yml文件代码的格式 Value注解 properties 缺点分析properties VS yml实现一个验证码程序 配置文件 配置文件作用 整个项目的重要信息我们都会配置在配置文件中&#xff0c;比如说我们数…

VMware虚拟机-设置系统网络IP、快照、克隆

1.设置网络IP 1.点击右上角开关按钮-》有线 已连接-》有线设置 2.手动修改ip 3.重启或者把开关重新关闭开启 2.快照设置 快照介绍&#xff1a; 通过快照可快速保存虚拟机当前的状态&#xff0c;后续可以使用虚拟机还原到某个快照的状态。 1.添加快照(需要先关闭虚拟机) 2.在…

电子商务网站(网上商店PetShop)

PetShop是一个范例&#xff0c;微软用它来展示.Net企业系统开发的能力。PetShop随着版本的不断更新&#xff0c;至现在基于.Net2.0的PetShop 4.0为止&#xff0c;整个设计逐渐变得成熟而优雅&#xff0c;有很多可以借鉴之处。PetShop是一个小型的项目&#xff0c;系统架构与代码…

【设计模式深度剖析】【2】【结构型】【装饰器模式】| 以去咖啡馆买咖啡为例 | 以穿衣服出门类比

&#x1f448;️上一篇:代理模式 | 下一篇:适配器模式&#x1f449;️ 目 录 装饰器模式定义英文原话直译如何理解呢&#xff1f;4个角色类图1. 抽象构件&#xff08;Component&#xff09;角色2. 具体构件&#xff08;Concrete Component&#xff09;角色3. 装饰&#xf…

【调试笔记-20240526-Linux-在 OpenWrt-23.05 发行版上安装 cpolar】

调试笔记-系列文章目录 调试笔记-20240526-Linux-在 OpenWrt-23.05 发行版上安装 cpolar 文章目录 调试笔记-系列文章目录调试笔记-20240526-Linux-在 OpenWrt-23.05 发行版上安装 cpolar 前言一、调试环境操作系统&#xff1a;Windows 10 专业版调试环境调试目标 二、调试步骤…

【找出第 K 大的异或坐标值】python

4层循环暴力超时 class Solution:def kthLargestValue(self, matrix: List[List[int]], k: int) -> int:nums[]for a in range(len(matrix)):for b in range(len(matrix[0])):num0for i in range(a1):for j in range(b1):num^matrix[i][j]nums.append(num)nums.sort()retu…

部门来了个测试开发,听说是00后,上来一顿操作给我看蒙了...

公司新来了个同事&#xff0c;听说大学是学的广告专业&#xff0c;因为喜欢IT行业就找了个培训班&#xff0c;后来在一家小公司实习半年&#xff0c;现在跳槽来我们公司。来了之后把现有项目的性能优化了一遍&#xff0c;服务器缩减一半&#xff0c;性能反而提升4倍&#xff01…

Docker自定义镜像

镜像 镜像包含了应用程序、程序运行的系统函数库、运行配置等文件的文件包。构建自定义镜像就是把上述文件打包的过程。 镜像结构 入口&#xff08;entrypoint&#xff09;&#xff1a;镜像运行入口&#xff0c;一般是程序的启动脚本和参数 层&#xff08;layer&#xff09;&am…

Tensorflow 2.0 安装过程

第一步&#xff1a;进入国内清华软件网站 anaconda | 镜像站使用帮助 | 清华大学开源软件镜像站 | Tsinghua Open Source Mirroranaconda 使用帮助 | 镜像站使用帮助 | 清华大学开源软件镜像站&#xff0c;致力于为国内和校内用户提供高质量的开源软件镜像、Linux 镜像源服务&…

怎么在Qt Designer设计的界面上显示Matplotlib的绘图?

首先&#xff0c;利用Qt Designer设计界面。 设计好后保存为ui文件。 接着&#xff0c;将ui文件转为py文件。 我喜欢在python中进行转换&#xff0c;因此把转换命令封装为函数&#xff0c;运行一下即可。 import os # pyuic5 -o output_file.py input_file.ui #通过命令把.ui…

OFDM 802.11a的FPGA实现(二十)使用AXI-Stream FIFO进行跨时钟(含代码)

目录 1.前言 2.AXI-Stream FIFO时序 3.AXI-Stream FIFO配置信息 4.时钟控制模块MMCM 5.ModelSim仿真 6.总结 1.前言 至此&#xff0c;通过前面的文章讲解&#xff0c;对于OFDM 802.11a的发射基带的一个完整的PPDU帧的所有处理已经全部完成&#xff0c;其结构如下图所示&…

老外卖27刀每月的教程已经更新

用了两天半的时间&#xff0c;边学习&#xff0c;边整理了一份老外的视频教程&#xff0c;涉及Facebook&#xff0c;YouTube&#xff0c;tiktok等大的流量平台&#xff0c;有案例&#xff0c;有分析&#xff0c;有如何做。 这个教程是老外讲的&#xff0c;没有什么玄乎的塑造价…

RabbitMQ-默认读、写方式介绍

1、RabbitMQ简介 rabbitmq是一个开源的消息中间件&#xff0c;主要有以下用途&#xff0c;分别是&#xff1a; 应用解耦&#xff1a;通过使用RabbitMQ&#xff0c;不同的应用程序之间可以通过消息进行通信&#xff0c;从而降低应用程序之间的直接依赖性&#xff0c;提高系统的…

微软刚发布的Copilot+PC为什么让Intel和AMD尴尬?2024 AI PC元年——产业布局及前景展望

美国东部时间5月20日在微软位于华盛顿的新园区举行的发布会上&#xff0c;宣布将旗下AI助手Copilot全面融入Windows系统&#xff0c;能够在不调用云数据中心的情况下处理更多人工智能任务。 “将世界作为一个提示词就从Windows系统开始”。微软的新PC将是“CopilotPC”&#xf…

spiderfoot一键扫描IP信息(KALI工具系列九)

目录 1、KALI LINUX简介 2、spiderfoot工具简介 3、在KALI中使用spiderfoot 3.1 目标主机IP&#xff08;win&#xff09; 3.2 KALI的IP 4、命令示例 4.1 web访问 4.2 扫描并进行DNS解析 4.3 全面扫描 5、总结 1、KALI LINUX简介 Kali Linux 是一个功能强大、多才多…

Google发布的CAT3D,在1分钟内,能够从任意数量的真实或生成的图像创建3D场景。

给定任意数量的输入图像&#xff0c;使用以这些图像为条件的多视图扩散模型来生成场景的新视图。生成的视图被输入到强大的 3D 重建管道&#xff0c;生成可以交互渲染的 3D 表示。总处理时间&#xff08;包括视图生成和 3D 重建&#xff09;仅需一分钟。 相关链接 论文&#x…

mysql图形化界面及将mysql注册成后台程序

安装图形化界面版本 右键新建数据库 字符集使用utf8防止以后数据库中存在中文字符导致乱码 将mysql注册成后台程序 cmd进入命令行界面 切换路径到cd /mysql/bin 将mysql注册成后台程序 mysqld.exe --install mysql1 (失败&#xff0c;说明没有权限) 以管理员身份打开成功…

未授权访问:Hadoop 未授权访问漏洞

目录 1、漏洞原理 2、环境搭建 3、未授权访问 4、通过REST API命令执行 防御手段 今天继续学习各种未授权访问的知识和相关的实操实验&#xff0c;一共有好多篇&#xff0c;内容主要是参考先知社区的一位大佬的关于未授权访问的好文章&#xff0c;还有其他大佬总结好的文章…

Qt 在windows下显示中文

Qt在windows平台上显示中文&#xff0c;简直是一门玄学&#xff0c;经过测试&#xff0c;有如下发现&#xff1a; 1&#xff0c; 环境&#xff1a;Qt 5.15.2 vs2019 64位 win11系统 默认用Qt 创建的文件使用utf-8编码格式&#xff0c;此环境下 中文没有问题 ui->textE…

手写tomcat(Ⅲ)——tomcat动态资源的获取

仿写tomcat的Servlet接口体系 之前写过一篇博客&#xff0c;Tomcat的Servlet-GenericServlet-HttpServlet体系的具体结构&#xff0c;以及Servlet的生命周期 Servlet讲解 想要模仿tomcat获取动态资源&#xff0c;就需要我们自己仿写一个Servlet接口体系 主要包括&#xff1a…