C++类型转换,特殊类设计,IO流

1.类型转换

什么是类型转换?我们知道有些数字类型可以相互转换,如double类型可以转换为int类型,这样的转换会发生切割将double类型的小数部分切割掉丢失精度;还有在前面的多态那块有一个虚函数指针表,这个虚函数指针表存储在类最前面的4到8个字节;我们想获得这个地址于是用指针强制转换类的地址为虚函数的函数指针类型,从而获得虚函数指针表的首地址;这也是一种类型转换,但这样的类型转换是需要带()强转的;

1.1 C语言类型转换

1.隐式类型转换

上面说到了我们以往的类型转换一般都是直接将某个类型的值赋给另一个类型,这样就完成了类型转换,这其实是编译器底层进行了隐式类型转换,让具有相似概念的数据可以转换

double a=10.21;

int b=a;

//这样的转换伴随着精度的降低

这样的代码在编译器上是可以直接编译通过的,是编译器进行了隐式类型转换

2.显式类型转换(强转)

还有一些类型是不能直接转换的,就需要进行显式类型转换(强转)

    int a = 10;
    int b = (int)&a;

//这样的转换使得&a地址数据被截断了

 原本a的地址是没有办法传递给b的但是由于,()中的强制类型转换,使得b强行获得了a的地址,但由于a地址数据大于int,所以截断a地址数据赋值给b;

类型的转换有时是存在问题的,我们应该严谨的对待类型的转换,防止出现不必要的错误;

1.2 C++类型转换

C++继承了C的所有内容,自然上面的转换C++也是拥有的,但是C++祖师爷也研发了C++自己的类型转换方式,这些转换方式有作用,但作用不是非常大,其目的重要之处是为了规范程序员编写代码的行为,在有些管理严格的计算机公司会要求程序员在类型转换时按照必须下面的四种方式进行转换;不要使用如()的不明确的转换;

1.2.1 static_cast

当转换类型与被转换数据类型有相似的意义时,如不同类型指针的转换,整数与浮点数之间的转换,这些转换都是具有相似意义的转换;

    double a = 10.21;
    int b = static_cast<int>(a);

    在linux线程函数中经常用到将空指针转换为某种数据类型的指针:

    void*args;

    threadData* data=static_cast< threadData*>(a);

 1.2.2 reinterpret_cast

这个转换代表着将有一定的关联但是没有相似意义的两个类型进行转换,通常用来表示两个完全不同类型的转换:

    int a = 10;
    int b = reinterpret_cast<int>(&a);

    double c = 10.11;
    char d = reinterpret_cast<int>(&c);

1.2.3 const_cast 

这个转换一般用来删除具有常性数据的常性:

    //去除优化,防止常量替换
    volatile const int a = 10;
    int* b = const_cast<int*>(&a);//const_cast<>中的类型必须是指针或者引用

测试时发现的小问题: 

在vs2022与linux下都存在常量替换的优化所以用volatile去掉优化效果;

另外在测试的过程中还出现了cout<<&a输出1的<<输出流类型匹配不明确的问题;

1.2.4 dynamic_cast

这个转换是用来对父类引用或指针进行安全转换的,有下面几个需要注意的地方;

1.被转换的父类必须是指针或者引用;

2.被转换的父类指针与引用接收的是子类时才可以成功转换,否则会返回空指针或者抛出std::bad_cast异常;(向下转换)

3.父类成员函数中必须有虚函数;

//测试dynamic_cast
class A {
public:virtual void fun()//使用dynamic_cast转化的父类必须包含虚函数{cout << "A()" << endl;}
private:int _a;
};class B :public A
{
public:void fun(){cout << "B()" << endl;}
private:int _b;
};void getfun(A* a)
{B* b = dynamic_cast<B*>(a);if (b){cout << "success" << endl;}else{cout << "fail" << endl;}
}void test5()
{A a;B b;getfun(&a);getfun(&b);
}

上面就是C++四大类型转换的基本内容

2.特殊类设计

2.1只能在堆上创建的类 

法1:将构造函数设置为私有成员,将拷贝构造与赋值重载删去防止使用其在栈上构造,最后创建一个静态成员函数,使得可以调用此接口在堆上创建对象;

法2:将析构函数设置为私有成员,剩余步骤同上;

下面使用的是法1:

//只能在堆上创建的类
class onlyHeap {
public:static onlyHeap* getonlyHeap(int a = 10){return new onlyHeap(a);}void deleteData() {//进行析构cout << "~onlyHeap()" << endl;}
private:onlyHeap(int a = 10):_a(a){cout << "onlyHeap()" << endl;}onlyHeap(const onlyHeap& a) = delete;onlyHeap& operator =(const onlyHeap& a) = delete;int _a;
};

2.2只能在栈上创建类

1.也是一样将构造函数私有化,并写一个静态的创建类对象的接口即可。

2.最为保险是将类中的operator new与operator delete也禁掉 ;

//设计只能在栈上创建的类
class onlyStack {
public:static onlyStack getonlyStack(int a = 10){onlyStack s;return s;}~onlyStack() {//进行析构cout << "~onlyStack()" << endl;}//可以直接禁掉下面两个函数也可做到只能在栈上创建void* operator new(size_t size) = delete;void operator delete(void * d) = delete;
private:onlyStack(int a = 10):_a(a){cout << "onlyStack()" << endl;}int _a;
};void test7()
{onlyStack s=onlyStack::getonlyStack();//下面无法创建//onlyStack s1 = new onlyStack;
}

 

2.3让一个类无法被继承

1.使用final关键字,在类名后声明,使得这个类无法再被继承;

2.私有化构造函数,让子类无法调用

2.4让一个类禁用拷贝构造

1.delete删除默认拷贝构造与赋值重载;

2.声明并私有

2.5单例模式与懒汉饿汉方式

这其实在我前面的linux博客中就有说明过,可以联系前面linux的博客理解;

单例模式是编程设计模式中23种中的一种;

饿汉单例:

//C++下实现单例饿汉模式
class hangry{
public:static hangry* getHangry(){return &_h;}hangry(const hangry& h) = delete;hangry& operator=(const hangry& h) = delete;~hangry(){cout << "~hangry()" << endl;}
private:hangry(){cout << "hangry()" << endl;}static hangry _h;//静态变量在程序创建时一同创建
};
hangry hangry::_h;//这里得初始化一下,不然没法创建int main()
{return 0;
}

懒汉单例在前面linux那实现过完成的了,这里就不是实现了;

3.C++中的IO流

3.1 C++中庞大的IO流体系

什么是流?我们可以理解为具有方向,进行连续传递的数据叫做流;

在我们C++库中有一个非常大的体系是关于IO流,数据可以通过这个IO流的封装进行流动,下面是这个体系的大致构成:

ios是io流体系中所有类的基类,所有类都继承与ios类(ios_base是由于不同国家编码格式和一些设置存在所以为基类的基类);我们经常使用是iostream类是继承istrem和ostrem,这里有一个菱形继承,存在数据冗余和二义性的问题,要通过虚基表来解决;后面的文件流类fstream也是继承与istream与ostream;字符串流同理;下面说一些值得注意的地方:

1.上面的这些类有很多接口,我们虽然不常用但这些接口是真正存在的:

比如istream类,它有一个我们经常用到的对象cin,它是istream中实例化出的一个全局对象,istream中有非常多的接口,我们的cin也就可以调用这些接口:

2.我们经常使用的cin,cout,cerro这些都是实例化出的全局对象,是标准库的实现自动完成

3.缓冲区问题,我们输入输出的数据会先进入缓冲区再放入内存中的文件或者我们开辟的数据空间中,而cin,cout,cerro这些在读取数据时会通过一些分割符来读取,当遇到回车或者空格时会刷新缓冲区将数据读入;所以由此同理C语言也是有这样的缓冲区的是与C++的缓冲区独立的,一般我们程序会自动维护C语言与C++缓冲区同步,我们可以调用iostream类中的sync_with_stdio接口关闭同步提高效率,但是这样也可能会出现数据不同步导致的问题,当只使用C或C++接口时可以调用sync_with_stdio(false)关闭,提高效率;

3.2运算符重载与类型转换运算符(类型重载)

3.2.1 运算符重载

在我们很早之前刚开始学习C++的时候,我们就学过了运算符重载,我们知道可以通过重载运算符的行为来实现我们想要的动作,其实不仅仅我们是这么做的,库中也是这么做的,我们定义的是自定义类型,输出我们自定义的数据,而库中定义的是内置类型,输出的是内置类型的数据;而想要对这些数据用运算符进行操作,也就调用是库中所重载的行为,所以其实内置类型也不是什么很高大上的存在,也和我们实现的内置类型一般,重载了运算符的操作,不过是库来实现重载的罢了,我们不知道它底层如何实现的而已;

重载实现与调用的过程 :

上面我们说完了运算符重载我们下面谈一谈类型重载,在上面的内容中,我们学到了C++的四大类型转换方式,这些转换方式是让转换更加清晰明了;这样的转换可以进行的原因是为什么呢?

3.2.2类型转换

1.自定义类型<——内置类型

2.自定义类型<——自定义类型

上面这两种转换为什么可行,这样的转换是因为我们实现了自定义类型的构造函数,让后边的这些被转换类型作为参数给自定义类型,从而调用自定义类型的构造函数例如:

//				类型转换与类型重载
class test_string
{
public:test_string(const char* str){_str = new char[10];strcpy(_str,str);}char* _str;
};void test8()
{test_string s = "hello";cout << s._str << endl;
}

test_string s = "hello";

上面的const char*内置类型转换为了test_string自定义类型就是因为构造函数的存在,使得内置类型找到了自自定义类型的构造,从而调用;那么自定义类型转换为自定义类型也是同理的;

可以还有两种转换下面这样的类型是如何进行转换的呢:

1.内置类型<——内置类型

2.内置类型<——自定义类型

while(sacnf)输出的小例子:

我们在最前面学习c语言的时候题目时是不是会遇到这样的重复输入:

while(scanf("%d",&a)!=EOF){} 

当一个程序有这样的代码时,我们哪个时候怎么输入都无法正常退出,除非我们关闭进程;后来随着我们慢慢的学习知道了ctrl+c和ctrl+z(linux下为ctrl+d)可以退出我们的while循环结束进行,但还是不知道其正常退出的原因,再后来我们学习了linux信号,知道了ctrl+c是发送信号杀死进程;而现在我们将解开ctrl+z的面纱;ctrl+z其实就是我们上面while的判断条件EOF,当我们按下ctrl+z时会发送EOF文件结束符到内存中,while识别到了EOF自然就退出进程了;

小tip:

我在vs2022下操作发现,输入三次ctrl+z后再输入回车才正常退出,我也很好奇,为什么要输入三次才判断退出,非常奇怪,我在codeblock和linux下进行都只需要输入一次就会正常退出;

那上面的操作和我们的类型转换有什么关系呢?

int scanf(const char *format, ...);

int是scanf的返回值,当scanf读取到EOF时也会返回EOF从而让while的条件判断为假,从而退出;而我们c++中while(cin>>a) 这也是具有相同效果的而cin>>的返回值是一个istream对象,这个istream对象为什么可以作为bool内置类型的值来进行判断空与非空呢?

3.2.3 类型转换运算符

这里就是问题的关键所在,因为istream类中存在一个类型转换的重载:

将istream的类型直接转换为了bool,从而进行判断;

我们的内置类型数字0为falsee非0为true,指针空指针为false,非空指针为true,它们其实在内部也是进行了类型重载的,可以将我们的类型重载为bool类型,从而进行空与非空的判断;

看下面的代码实现:

//				类型重载
struct A {A(int a=0):_a(a){}operator bool(){if (_a == 0)return false;elsereturn true;}operator int(){return _a;}int _a;
};
void test9()
{A a(100);if (a)cout << "true" << endl;elsecout << "false" << endl;int b = a;cout << b << endl;
}

上面的现象中自定义类型也可以作为bool值来进行判断了,这就是类型重载;

同理转换为其他内置类型也是可以的:

这就是类型的重载

 3.3 C++文件流

我们前面学过C语言的文件操作,也学习了linux下底层的文件操作,现在我们来看看C++面向对象语言的文件操作是怎么样的:

C++中文件流依然是被封装成为了三个类,ifstream和ofstream以及iofstream;

3.3.1 二进制读写操作

//							文件流操作
void test10()
{ofstream of("text.txt", ios_base::out | ios_base::binary);const char* str = "你好!看得到我吗?";of.write(str, strlen(str));of.close();//一定一定记得要关闭上面的文件,否则会对文件进行上锁,使得无法再次以读形式打开ifstream in("text.txt", ios_base::in | ios_base::binary);char buffer[100] = { 0 };in.read(buffer, sizeof(buffer));cout << buffer << endl;
}

这样我们成功的读到了数据:

 

但是二进制的读写存在一些问题,如果读写的是一个容器,或者是堆上开辟的空间,传递的是指针,会发生这样的问题:

改写代码,写入数据有容器string

myData类实现

class myData {
public:myData(const string& str = ""):_str(str){}~myData(){cout << "~myData()" << endl;printf("%p\n", _str.c_str());}string _str;
};
ostream& operator<<(ostream& of,const myData& d)
{return of << d._str;}istream& operator>>(istream& in, myData& d)
{return in >> d._str;
}
void test11()
{myData d("hellohellohellohellohellohellohellohellohellohellohellohellohellohello");ofstream of("text.txt", ios_base::out | ios_base::binary);of.write((char*)&d, sizeof(d));of.close();//一定一定记得要关闭上面的文件,否则会对文件进行上锁,使得无法再次以读形式打开ifstream in("text.txt", ios_base::in | ios_base::binary);myData d1;in.read((char*) & d1, sizeof(d1));cout << d1._str << endl;
}

 这下面之所以要给d这么长的字符,是因为string在vs2022的底层实现下是存在一个buffer的,这个buffer是在数据量小的时候就会在buffer中创建数据而不是通过指针在堆上创建,buffer是直接存在于string类对象中的,如果不写这么长的字符,就无法看到两次析构的现象;

所以在有容器写入时我们一定要注意要进行文本读写;

3.3.2 文本读写操作

//文本读写操作
void test12()
{myData d("hellohellohellohellohellohellohellohellohellohellohello");ofstream of("text.txt");//默认以文本形式写入of << d;of.close();ifstream in("text.txt", ios_base::in | ios_base::binary);myData d1;in >> d1;cout << d1 << endl;
}

 

 总结文件流操作:

1.C++文件流操作中创建ofstream与ifstream对象,它们默认创建都是以文本读或者文本写的形式创建的,如果想切换为二进制读写需要向上面那样带上两个设置的 |(与)

2.我们在进行文件操作的时候,如果创建了一个文件对象,我们使用完之后一定要调用close接口来关闭使用完了的对象,否则对象占用文件会导致其他对象无法打开这个文件完成操作;

3.文件写入操作要记得带上分割符,我们可以自己设置也可以使用默认的空格,回车,制表符;但是需要注意一旦我们是定义的自己设置的分割符,那么,我们在文本读的时候要使用getline来设置第三个参数作为分割符,否则会发生想不到的错误,下面的stringstream也有写当没有分隔符时所产生的现象;

4.对于容器的读写只能使用文本读写,使用二进制读写会发生野指针的问题;

5.文本读写有时候放在记事本中会有乱码,这是因为记事本的编码格式和你编译器编译的可执行程序编码格式不同,就像vs2022是utf-8编码而记事本一般是utf-16,改写编码格式即可;

3.4 stringstream类

3.4.1 将各种数据类型转换为字符串类型

//将各种数据类型转换为字符串类型
void test14()
{int a = 10;double b = 10.12;bool c = true;char d = 'a';stringstream ss;ss << a << b << c << d;cout << ss.str() << endl;
}

现象:

 

如果想把放入了stringstream中的数据再放回原有类型,要记得str("")置空stringstream底层的string字符串与clear()清空某些控制才能让 stringstream多次进行转换;

stringstream ss;

。。。。。转换操作

ss.str("");       //多次转换操作中间都必须得有这两步操作;

ss.clear();

。。。。。转换操作

3.4.2 序列化与反序列化

stringstream是字符串流类,在C语言中对应的是sprintf和sscanf,用来将数据转换为字符串格式;我们也将数据转换为字符串称为序列化,将字符串转化为数据称之为反序列化

不过序列化和反序列的操作有更好的方法来处理,stringstream只适用与简单的数据处理,可以用xml和json来处理,这里我并没有学过,只是听过所以还需要后续的学习来验证

接下来我们用stringstream来完成一下简单的序列化和反序列化操作:

//使用stringstream完成简单的序列化反序列化操作
class conmuni {
public:friend ostream& operator<<(ostream& of, const conmuni& d);friend istream& operator>>(istream& in, conmuni& d);conmuni(const string& id = "", double time = 0, const string& msg = ""):_id(id), _time(time), _msg(msg){}
private:string _id;double _time;string _msg;
};ostream& operator<<(ostream& of, const conmuni& d)
{//这里这些回车一起写入stringstream的底层中//当进行读时,这些回车就会作为分隔符读入//可以删除这些endl去调试看一下现象//of << d._id << d._time << d._msg;of << d._id << endl << d._time << endl << d._msg << endl;return of;
}istream& operator>>(istream& in, conmuni& d)
{in >> d._id >> d._time >> d._msg;return in;
}void test13()
{conmuni a("张三", 9.12, "今天真的好累哇!");//让回车作为分割符stringstream ss;conmuni a1;ss << a;cout << "序列化数据获得:" << endl << ss.str() << endl;cout << "反序列化获得:" << endl;ss >> a1;cout << a1;
}

现象:

我们由此可知ss底层中的string是

string="张三\n9.12\n今天真的好累哇!\n\0";

我们上面的operator<<操作如果去掉所有的endl我们调式会看到这样的现象:

of << d._id << d._time << d._msg;

 

 

关于>>与<<重载的思考:

在上面的ss>>与ss<<操作上,其实我花了很长的时间思考为什么ss可以调用到我们写的

istream& operator>>(istream& in, conmuni& d)重载

ostream& operator<<(ostream& of, const conmuni& d)重载

1.明明我们写的重载是iostream类的对象呀;为什么stringstream类调用了这个重载呢?

其实这就是继承所带来的优势,因为stringstream是iostream的子类,所以stringstream作为子类对象赋值给父类的引用,从而找到了这个两个符合条件的函数,

2.之后为什么内部的实现又是stringstream对象完成的呢明明第一个参数是父类的引用呀?

这就涉及到了运算符重载的另一个内容重载解析,编译器对于运算符重载函数会通过这个iostream&中实际的对象来寻找匹配的函数;而iostream&中实际的对象是stringstream,所以调用的内部的实现是stringstream的>>与<<;

通过上面的两步操作成功的实现了类似与多态的行为,一样的操作可以调用不同的函数重载;

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

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

相关文章

ZYNQ 入门笔记(二):动态时钟

文章目录 1 概述1.1 DRP1.2 AXI4-Lite 2 示例2.1 单时钟输出2.2 多时钟输出 3 参考文档 1 概述 Clocking Wizard 可通过配置内部寄存器动态调整输出频率&#xff0c;配置接口可选 DRP 或 AXI4-Lite&#xff0c;其中 AXI4-Lite 实际上是对 DRP 接口的封装 1.1 DRP 通过 DRP 接…

用RNN(循环神经网络)预测股票价格

RNN&#xff08;循环神经网络&#xff09;是一种特殊类型的神经网络&#xff0c;它能够处理序列数据&#xff0c;并且具有记忆先前信息的能力。这种网络结构特别适合于处理时间序列数据、文本、语音等具有时间依赖性的问题。RNN的核心特点是它可以捕捉时间序列中的长期依赖关系…

C2免杀--手工shellcode编译,shellcode免杀思路

前言 欢迎来到我的博客 个人主页:北岭敲键盘的荒漠猫-CSDN博客 本文主要整理C2免杀中 shellcode代码免杀的相关部分 shellcode概念 我们也不啰嗦&#xff0c;我直接直观的描述一下他。 他就是一串机器能运行的代码&#xff0c;但是他不是正统的python&#xff0c;c&#xff…

中伟视界:煤矿皮带运输机异物监测AI算法能检测哪几种异物,通过什么方式来判断异物?

在矿山运输系统中&#xff0c;运输皮带上可能出现各种异物&#xff0c;如大煤块、锚杆、钻杆、煤矸石、木板、铁棍等。这些异物会对运输系统造成损害&#xff0c;影响生产效率&#xff0c;甚至引发安全事故。为了实时监测并识别这些异物&#xff0c;现代技术采用AI算法进行分析…

QT串口读取Serial->readAll()踩过的坑

QT串口读取Serial->readAll接收不完全踩过的坑 Chapter1 QT串口读取Serial->readAll()踩过的坑坑一&#xff1a;坑二 Chapter2 [QT串口上位机BUG解决]json解析数据bug以及接收数据问题问题描述原因分析&#xff1a;解决方案&#xff1a;一、是数据采集端&#xff08;单片…

Go语言?IDEA能支持吗?增删查走起?

序&#xff1a; 最近突然身边突然开始冒出关于go语言的只言片语&#xff0c;很好奇这个go语言是怎么样的&#xff1f;这几天有空就会去网上浏览一遍各位大咖的简介。这边主要是已学习为目的&#xff0c;关键人家都说它好这边记录一下学习过程的进坑和爬坑过程供大家娱乐一下。…

OpenCV结构分析与形状描述符(8)点集凸包计算函数convexHull()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 查找一个点集的凸包。 函数 cv::convexHull 使用斯克拉斯基算法&#xff08;Sklansky’s algorithm&#xff09;来查找一个二维点集的凸包&#…

视频回放 | DolphinDB 2024 年度峰会主会场演讲精彩回顾

9 月 6 日&#xff0c;“以实时&#xff0c;见未来” DolphinDB 2024 年度峰会在杭州成功举办。上午&#xff0c;DolphinDB 创始团队与技术团队分别从不同方面介绍了 DolphinDB 这一年来的创新和突破。没来到现场没关系&#xff0c;现在就为您送上全场完整视频回放~&#xff08…

Pyspark下操作dataframe方法(1)

文章目录 Pyspark dataframe创建DataFrame使用Row对象使用元组与scheam使用字典与scheam注意 agg 聚合操作alias 设置别名字段设置别名设置dataframe别名 cache 缓存checkpoint RDD持久化到外部存储coalesce 设置dataframe分区数量collect 拉取数据columns 获取dataframe列 Pys…

CnCrypt(磁盘加密工具绿色版是一款功能强大磁盘加密工具,供大家学习研究参考

CnCrypt(磁盘加密工具)特点 加密单个分区或整个硬盘,所有加密都是以分区为基础的 提供两级方案,以应对被强迫说出密码的情况(如抢劫。隐藏分区(覆盖式密码术,steganography)无法探测到CnCrypt 加密分区(加密数据会被认为是随机数据)。 CnCrypt(磁盘加密工具)特色 1、加密U…

ucx 编译安装检验方式备忘

1&#xff0c; 下载配置编译 预备依赖&#xff1a; sudo apt-get install valgrind sudo apt-get install libibverbs-dev librdmacm-dev 1.1 下载源码 git clone --recursive https://github.com/openucx/ucx.git cd ucx/ git checkout v1.16.0 git 下来的代码&#xff0c;…

《Diffusion Models Without Attention》CVPR2024

摘要 这篇论文探讨了在高保真图像生成领域&#xff0c;去噪扩散概率模型&#xff08;Denoising Diffusion Probabilistic Models, DDPMs&#xff09;的重要性。尽管DDPMs在捕捉复杂视觉分布方面表现出色&#xff0c;但在高分辨率图像生成上面临显著的计算挑战。现有的方法&…

Vue邮件发送:如何有效集成邮件发送功能?

vue邮件发送功能实现方法&#xff1f;Vue邮件发送性能怎么优化&#xff1f; 无论是用户注册验证、密码重置&#xff0c;还是通知提醒&#xff0c;邮件发送功能都能提供重要的支持。本文将详细探讨如何在Vue项目中有效集成邮件发送功能&#xff0c;确保邮件能够准确、及时地送达…

macos 系统文件操作时提示 Operation not permitted 异常解决方法 , 通过恢复模式 开启 /关闭 SIP方法

在macos系统中操作系统文件时提示 Operation not permitted 这个异常, 原因是因为在macos 10.11以上版本中默认启用了 SIP( System Integrity Protection )机制对系统文件进行保护, 要解决这个问题我们需要关机, 然后进入mac的恢复模式 : 在按电源键开机的同时, 一直按住 co…

【机器学习】马尔可夫随机场的基本概念、和贝叶斯网络的联系与对比以及在python中的实例

引言 马尔可夫随机场&#xff08;Markov Random Field&#xff0c;简称MRF&#xff09;是一种用于描述变量之间依赖关系的概率模型&#xff0c;它在机器学习和图像处理等领域有着广泛的应用 文章目录 引言一、马尔科夫随机场1.1 定义1.2 特点1.3 应用1.4 学习算法1.5 总结 二、…

UG/NX加载插件失败的原因汇总

在自己的电脑上运行得好好的插件&#xff0c;部署到客户的电脑上出现未注册的命令错误或者“未能加载图像”的错误 1.首先检查插件的所有依赖是否齐全&#xff0c;确保齐全 2.这个问题在网络上搜索一番&#xff0c;大多数都是不知所云&#xff0c;后来看到这一篇文章【UG二次…

C++的流提取(>>)(输入) 流插入(<<)(输出)

什么是输入和输出流 流提取&#xff08;<<&#xff09;(输入) 理解&#xff1a;我们可以理解为&#xff0c;输入到io流里面&#xff0c;比如是cin&#xff0c;然后从输入流中读取数据 流插入&#xff08;<<&#xff09;&#xff08;输出&#xff09; 理解&#xff…

直播相关02-录制麦克风声音,QT 信号与槽,自定义信号和槽

一 信号与槽函数 #include "mainwindow.h" #include <QPushButton> #include <iostream> using namespace std;//我们的目的是在 window中加入一个button&#xff0c;当点击这个button后&#xff0c;关闭 MainWindow 。 MainWindow::MainWindow(QWidget …

828华为云征文 | 华为云Flexus X实例上实现Docker容器的实时监控与可视化分析

前言 华为云Flexus X&#xff0c;以顶尖算力与智能调度&#xff0c;引领Docker容器管理新风尚。828企业上云节之际&#xff0c;Flexus X携手前沿技术&#xff0c;实现容器运行的实时监控与数据可视化&#xff0c;让管理变得直观高效。无论是性能瓶颈的精准定位&#xff0c;还是…

TS 常用类型

我们经常说TypeScript是JavaScript的一个超级 TypeScript 常用类型 TypeScript 是 JS 的超集&#xff0c;TS 提供了 JS 的所有功能&#xff0c;并且额外的增加了&#xff1a;类型系统 所有的 JS 代码都是 TS 代码 JS 有类型&#xff08;比如&#xff0c;number/string 等&…