C++类与对象—下

news2024/11/24 20:49:59

本期我们继续学习类与对象,没有看过上和中的小伙伴建议先看前两期内容

(2条消息) C++类与对象—上_KLZUQ的博客-CSDN博客

(2条消息) C++类与对象—中_KLZUQ的博客-CSDN博客

目录

1.再谈构造函数

1.1构造函数体赋值

1.2初始化列表

1.3 explicit关键字

2. static成员

2.1 概念

2.2 特性

3.友元

3.1友元函数 

3.2友元类

4.内部类

5.匿名对象

7.再次理解类和对象


1.再谈构造函数

1.1构造函数体赋值

在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值
class Date
{
public:
	Date(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
private:
	int _year;
	int _month;
	int _day;
};
虽然上述构造函数调用之后,对象中已经有了一个初始值,但是不能将其称为对对象中成员变量的初始化, 构造函数体中的语句只能将其称为赋初值 ,而不能称作初始化。因为 初始化只能初始化一次,而构造函数体 内可以多次赋值

1.2初始化列表

初始化列表:以一个 冒号开始 ,接着是一个以 逗号分隔的数据成员列表 ,每个 " 成员变量 " 后面跟一个 放在括 号中的初始值或表达式。
class Date
{
public:
	Date(int year, int month, int day)
		: _year(year)
		, _month(month)
		, _day(day)
	{}

private:
	int _year;
	int _month;
	int _day;
};

为什么需要初始化列表呢?因为在有些情况下,只能使用初始化列表来解决问题

【注意】
1. 每个成员变量在初始化列表中最多 只能出现一次 ( 初始化只能初始化一次 )
2. 类中包含以下成员,必须放在初始化列表位置进行初始化:
引用成员变量
const 成员变量
自定义类型成员 ( 且该类没有默认构造函数时 )

 我们用下面的代码来举例

class A
{
public:
	A(int a)
		:_a(a)
	{}
private:
	int _a;
};
class B
{
public:
	B(int a, int ref)
		:_aobj(a)
		, _ref(ref)
		, _n(10)
	{}
private:
	A _aobj; // 没有默认构造函数
	int& _ref; // 引用
	const int _n; // const 
};

 我们一个一个来看

先看const成员,const成员不能在函数体内赋值 

不仅是const,引用也是一样的

原因是const和引用的特征是必须在定义时初始化

引用是别名,而const也只有一次初始化的机会

 我们创建对象时是对象的整体的定义,而对象的成员也需要一个地方定义,所以就有了初始化列表,选择初始化列表作为对象成员定义的地方,而我们之前在函数体里写的是初始化不叫初始化,而叫做赋值

而且我们上面也说了,初始化最多只能初始化一次

这里就初始化了两次,所以报错了

除了引用和const,自定义成员也必须在初始化列表初始化

我们先在A类里加一条输出语句,同时给a一个值

 

如果B的成员有A类,即使我们不在初始化列表去初始化A,他也会自动去调用进行初始化 

而如果是内置类型,比如int等等,就不做处理

 如果我们这里写了缺省值的话,就会用缺省值进行初始化

如果在初始化列表显示的写了,就不会用缺省值(之前说的那个C++11打的缺省值补丁就是给初始化列表打的)

我们把A类的缺省值去掉,然后这时编译会报错

 

此时我们可以在B里这样调用默认构造

 

我们运行也没有问题,当然A有默认构造时我们也可以这样调用

我们之前用两个栈实现了队列

 我们这里有两个构造函数,上面的第一个构造函数,我们什么也没写,但是我们创建MyQueue时也会进行初始化,原因是这两个栈会在初始化列表里进行初始化,就像我们上边的A类一样

 我们再回过头来看我们的类B和类A

所以当A这里没有默认构造时,我们这里不写就会报错

我们的代码还有问题,引用也是错误的

要这样写才行,刚才的写法出了作用域就销毁了,这样才是正确的

知道了上面的内容,可能就有同学迷惑了,既然有初始化列表,那为什么还需要函数体赋值呢?我们来看几个例子就知道了,他们各有各的用途

 比如我们的栈,我们甚至可以直接用初始化列表来完成,但是,我们在malloc空间后,我们还需要进行检查的,检查就只能写在函数体里,所以没有函数体是不行的

 再比如,我们要求还要把数组也初始化

 这些操作,没有函数体都是不行的

所以初始化列表和函数体都有存在的价值

尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量,一定会先使用初始化列表初始化

我们再看下一个内容

成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关 

class A
{
public:
	A(int a)
		:_a1(a)
		, _a2(_a1)
	{}

	void Print() {
		cout << _a1 << " " << _a2 << endl;
	}
private:
	int _a2;
	int _a1;
};
int main() {
	A aa(1);
	aa.Print();
}

大家想想这段代码运行后是什么?

A . 输出 1 1
B . 程序崩溃
C . 编译不通过
D . 输出 1 随机值

答案是D,原因就是上面说的,成员变量在类中声明次序就是其在初始化列表中的初始化顺序

即我们声明时的顺序先是_a2,然后是_a1,所以初始时会先初始化_a2,然后才是_a1 

这点是非常重要的,因为如果不注意的话,有人就可能会写出下面这种代码

 

我们声明时先声明了_a,然后才是_capacity,但是不知道上面知识的同学就可能会认为在初始化列表里先初始化的_capacity,然后在_a中使用没有问题,但这是错误的,因为代码会先初始化_a,此时_capacity是随机值,就会出现问题

所以我们建议声明顺序和定义顺序保持一致,这样就不会出现问题

这里的size也会走初始化列表,但是会是随机值, 我们可以给缺省值,这样在初始化列表时就会用缺省值了

 当然,我们还可以用函数体内赋值,大家根据场景选择即可

1.3 explicit关键字

我们知道,这段代码的aa1会调用a的构造函数,那aa2呢?

aa2这里是隐式类型转换,是整形转换为自定义类型

我们知道,在我们把x赋值给y时,会先产生临时变量,然后把临时变量赋值给y

上面的aa2也是一样的,数字2会先去调用构造函数,生成一个A类型的临时对象,然后再去调用拷贝构造,才有了aa2

不过这样做太繁琐了,老式的编译器可能还是这样,新的编译器都会优化为直接构造

 在同一个表达式里,连续的构造编译器基本都会优化,为了提高效率

这样是否我们就没办法证明我们上面说的呢?我们来看这个例子

 

aa3可以引用aa2,但是不能引用2,这些大家都可以理解 

 

 但是我们给aa3加上const就可以引用2了

如果我们运行的话还会调用一次构造 

因为临时对象具有常性,所以不能引用,但const引用可以

这个知识是在为我们的后续做铺垫,我们来看下面的例子(这里大家了解即可,我们后续会讲)

这两行代码的结果是一样的,但name1是构造,而name2是构造加拷贝构造加优化 

 上面的push就是老老实实的构造,然后传值,下面的就是隐式类型转换

如果没有隐式类型转换,我们只能老老实实的用第一种push,写起来就不如下面的方便

知道了什么是隐式类型转换,我们来看下面的内容

如果我们不想让转换发生,我们就可以加上一个关键字,explicit

 不能转换时下面就报错了,我们后续会学习智能指针,就不希望发生转换,需要使用到这个关键字

2. static成员

2.1 概念

声明为static的类成员称为类的静态成员,用static修饰的成员变量,称之为静态成员变量;用static修饰成员函数,称之为静态成员函数。静态成员变量一定要在类外进行初始化

如果我们想知道一个类当前有多少个对象,我们可以这样写

我们创建一个全局变量,构造和拷贝构造++,析构--

 但是这段代码有一个问题,全局变量我们是可以随意修改的,有点危险

所以我们就需要把这个变量封装一下,放到类里面

 成员变量和静态成员变量的区别是什么?

成员变量是属于每一个类对象的,而静态成员变量是属于类,属于类的每个对象共享,存储在静态区,生命周期是全局的

我们上面的静态成员 _scount只是声明

他不能在初始化列表初始化,因为初始化列表是对象的成员定义的地方,而静态成员不是属于某个对象的,所以他的定义要在类的外部

 

 因为是私有的,所以我们不能直接使用

如果写成公有的就可以,不过写成公有的就和全局的没什么区别了

我们可以通过公有的成员函数进行访问 

静态成员,只要突破类域和访问限定符就能访问

 不过更好的方式是使用静态成员函数,静态成员函数的特点是没有this指针,指定类域和访问限定符就可以访问,所以一般静态成员变量和静态成员函数是配套出现

 这样都是可以的

静态成员函数不能访问非静态成员变量,因为他没有this指针 

我们这样做相比全局变量的好处就是无法随意修改

 这里是声明,不能给缺省值,因为静态成员变量不能走初始化列表,我们只能在类外部定义

下面我们来看一道神奇的例题

 看题目非常简单,从1加到n即可,但是我们看条件,不能用乘除法,循环条件语句等等都不能使用,那该怎么办呢?我们看下面的解法

class Sum{
public:
    Sum(){
        _ret += _i;
        ++_i;
    }
    static int GetRet(){
        return _ret;
    }
private:
    static int _i;
    static int _ret;
};
int Sum::_i=1;
int Sum::_ret=0;
class Solution {
public:
    int Sum_Solution(int n) {
        Sum a[n];
        return Sum::GetRet();
    }
};

该解法非常巧妙,调用n次构造函数,用静态成员变量解决问题

我们继续看我们上面的代码

Func是可以调用GetACount的,即非静态可以调用静态

静态不能调用非静态,因为非静态成员函数要传递this指针

非静态函数内部是可能会进行修改成员变量的 

我们再看一个奇怪的例子

设计一个类,只能在栈上创建对象(或者堆上)

我们创建的变量,对象,一般都是在栈上面的,加static就在静态区

new我们之后会讲,现在大家只要知道这里的对象在堆上即可,我们该如何设计呢?

 我们分析一下,这三个对象,都需要调用构造函数

所以我们可以将构造函数私有化,这样都不能调用了

 

然后我们提供一个公有的方法(这里new返回的是一个指针 )

此时就会出现一个问题,我们调用函数需要对象,而我们创建对象又需要调用函数

所以这里我们就需要静态

 这里用静态的很好,完美解决了问题

我们来总结一下静态成员的特性

2.2 特性

1. 静态成员 所有类对象所共享 ,不属于某个具体的对象,存放在静态区
2. 静态成员变量 必须在 类外定义 ,定义时不添加 static 关键字,类中只是声明
3. 类静态成员即可用 类名 :: 静态成员 或者 对象 . 静态成员 来访问
4. 静态成员函数 没有 隐藏的 this 指针 ,不能访问任何非静态成员
5. 静态成员也是类的成员,受 public protected private 访问限定符的限制

3.友元

友元提供了一种突破封装的方式,有时提供了便利。但是友元会增加耦合度,破坏了封装,所以友元不宜多用。
友元分为: 友元函数 友元类

3.1友元函数 

友元函数 可以 直接访问 类的 私有 成员,它是 定义在类外部 普通函数 ,不属于任何类,但需要在类的内部声明,声明时需要加friend 关键字。

 我们之前重载<<时,使用了友元,但是友元一般是不推荐使用的,因为友元就像特例一样,让你和别人不一样,这是不好的

class Date
{
	friend ostream& operator<<(ostream& _cout, const Date& d);
	friend istream& operator>>(istream& _cin, Date& d);
public:
	Date(int year = 1900, int month = 1, int day = 1)
		: _year(year)
		, _month(month)
		, _day(day)
	{}
private:
	int _year;
	int _month;
	int _day;
};
ostream& operator<<(ostream& _cout, const Date& d)
{
	_cout << d._year << "-" << d._month << "-" << d._day;
	return _cout;
}
istream& operator>>(istream& _cin, Date& d)
{
	_cin >> d._year;
	_cin >> d._month;
	_cin >> d._day;
	return _cin;
}
int main()
{
	Date d;
	cin >> d;
	cout << d << endl;
	return 0;
}

我们可以使用get和set方法来解决友元的问题

而且使用友元函数还有别的问题,比如我们想把类里的成员变量_year改名为year,那么友元函数里也得进行改名

我们来总结一下友元函数的特点

友元函数 可访问类的私有和保护成员,但 不是类的成员函数
友元函数 不能用 const 修饰
友元函数 可以在类定义的任何地方声明, 不受类访问限定符限制
一个函数可以是多个类的友元函数
友元函数的调用与普通函数的调用原理相同

 除了友元函数,还有友元类,我们来看看什么是友元类

3.2友元类

友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。
友元关系是单向的,不具有交换性。
比如上述 Time 类和 Date 类,在 Time 类中声明 Date 类为其友元类,那么可以在 Date 类中直接访问 Time
类的私有成员变量,但想在 Time 类中访问 Date 类中私有的成员变量则不行。
友元关系不能传递
如果 B A 的友元, C B 的友元,则不能说明 C A 的友元。
友元关系不能继承,在继承位置再给大家详细介绍。

 友元函数是函数成为你的朋友,友元类就是这个类成为你的朋友,这个类可以随意访问你的私有和保护

class Time
{
	friend class Date; // 声明日期类为时间类的友元类,则在日期类中就直接访问Time类中的私有成员变量
public:
	Time(int hour = 0, int minute = 0, int second = 0)
		: _hour(hour)
		, _minute(minute)
		, _second(second)
	{}

private:
	int _hour;
	int _minute;
	int _second;
};
class Date
{
public:
	Date(int year = 1900, int month = 1, int day = 1)
		: _year(year)
		, _month(month)
		, _day(day)
	{}

	void SetTimeOfDate(int hour, int minute, int second)
	{
		// 直接访问时间类私有的成员变量
		_t._hour = hour;
		_t._minute = minute;
		_t._second = second;
	}

private:
	int _year;
	int _month;
	int _day;
	Time _t;
};

 现在我们把友元的声明屏蔽掉

这里就会报错

有人可能会纠结声明应该放在哪里,放在哪里都行,访问限定符只限制成员,成员是成员变量和成员函数,而友元声明只是声明,不受限制

4.内部类

概念: 如果一个类定义在另一个类的内部,这个内部类就叫做内部类 。内部类是一个独立的类,它不属于外部类,更不能通过外部类的对象去访问内部类的成员。外部类对内部类没有任何优越的访问权限。
注意: 内部类就是外部类的友元类 ,参见友元类的定义,内部类可以通过外部类的对象参数来访问外部类中的所有成员。但是外部类不是内部类的友元。
特性:
1. 内部类可以定义在外部类的 public protected private 都是可以的。
2. 注意内部类可以直接访问外部类中的 static 成员,不需要外部类的对象 / 类名。
3. sizeof( 外部类 )= 外部类,和内部类没有任何关系。

 我们一般定义类是在全局定义,而内部类就是定义在类的里面

class A
{
private:
	static int k;
	int h;
public:
	class B // B天生就是A的友元
	{
	public:
		void foo(const A& a)
		{
		}
	};
};
int A::k = 1;
int main()
{
	cout << sizeof(A) << endl;
	return 0;
}

大家先想想这段代码的计算结果是多少?

答案是4 

我们先看类A,他的成员变量有一个k,是static的,我们计算时是不需要计算k的,因为k没有存到对象里面

B对象的大小也不需要计算,因为A里面也没有B对象

除非我们定义一个B对象,才需要计算

此时的A和B其实是没有多大关系的,我们可以认为A就是一个大房子的图纸,B是买房子时房子里的赠品

我们不买房子是没有赠品的

当我们买了房子后,就可以得到赠品

如果我们把B设为私有,也是会受访问限定符的限制的

另外,内部类还是外部类的友元

内部类可以随意访问外部类的成员

C++其实是不太喜欢使用内部类的,不过某些场景使用还是不错的

我们再看这道题

class Solution {
    class Sum {
    public:
        Sum() {
            _ret += _i;
            ++_i;
        }
    };
public:
    int Sum_Solution(int n) {
        Sum a[n];
        return _ret;
    }
private:
        static int _i;
        static int _ret;
};
int Solution::_i = 1;
int Solution::_ret = 0;

 我们使用内部类修改代码如上,我们把sum类放到Solution类里,这样sum类就是Solution的友元,所以sum类可以随意访问Solution的成员,同时我们把_i和_ret改为Solution的成员,这样我们也不需要get函数,直接就可以返回_ret

内部类的优势在于我们在外部类定义的东西,我们可以在外部类使用,也可以在内部类使用

5.匿名对象

我们正常情况下是这样定义对象的

我们还可以使用这样的方式来定义对象

上面的叫做有名对象,下面的叫做匿名对象

匿名对象连名字都没有,我们该如何使用它呢?

我们调用有名对象是先创建,再调用,写了两行代码

我们使用匿名对象的话就只需要一行

 我们只调用一次的话就使用匿名对象,想调用多次就用有名的

匿名对象还有一个特点,就是即用即销毁,我们看A的析构函数打印的位置,在Sum_Solution前也有打印

匿名对象的生命周期在当前行,而有名对象的生命周期在当前函数局部域

匿名对象和临时对象类似,具有常性, 不能引用

 所以加上const可以引用

 加上const引用后,匿名对象的生命周期就会被延长,变为和引用的生命周期相同

我们之后可能会写一个push_back,如果用有名对象调用就是这样的,这样写了两行代码

使用匿名对象就可以一行解决

 

更简单一点就是用隐式类型转换(隐式类型转换会产生临时对象,const引用引用的是临时对象)

 我们一般会用第三种写法来写,这些知识要结合起来

另外,删除const下面的代码就编不过了,所以使用引用最好加上const,这里就体现了const引用的作用

我们继续往下看

class A
{
public:
	A(int a = 0)
		:_a(a)
	{
		cout << "A(int a = 0)" << endl;
	}
	A(const A& aa)
		:_a(aa._a)
	{
		cout<< "A(const A& aa)" << endl;

	}
	~A()
	{
		cout << "~A()" << endl;
	}
	A& operator=(const A& aa)
	{
		cout << "A& operator=(const A& aa)" << endl;
		if (this != &aa) {
			_a = aa._a;
		}
		return *this;
	}
private:
	int _a;
};

 这里有一个类A

我们有一个传值传参的Func1,传值传参要调用拷贝构造 

不想调用拷贝构造我们就使用引用,引用最好加上const 

另外,这两个函数构成重载,加上const,类型就不同了,但是这里存在调用歧义

 

我们写了一个Func3,传值返回,它会调用构造,拷贝构造,返回的是aa的拷贝构造

而我们使用Func4的写法就不会有拷贝

Func5返回的是拷贝的对象,但是我们不能用引用接收

但是加上const就可以了 

如果我们这样写,aa返回时会先拷贝构造临时变量,然后临时变量会拷贝构造ra 

 

 不过我们运行的话这里是一次,原因是这是编译器的优化,如果是老的编译器就是两次拷贝

在同一行的表达式里连续的构造和拷贝构造,编译器会进行优化,会合二为一甚至合三为一

就像这样的优化,构造+拷贝构造就优化成了构造 

如果我们是分开写的,先创建对象,再调用,是不会优化的

而一行内就会优化,这里也是构造+拷贝构造就优化成了构造 

 这里也是同理

所以我们传参的时候最好按照这些优化的方法写

 这样的差别就非常大了

上面的写法是一个构造加一个拷贝构造,下面是两个构造加一个拷贝构造加一个赋值

所以我们以后能写在一个步骤就写在一个步骤里,这样可以提高效率

7.再次理解类和对象

现实生活中的实体计算机并不认识,计算机只认识二进制格式的数据。如果想要让计算机认识现实生活中的实体,用户必须通过某种面向对象的语言,对实体进行描述,然后通过编写程序,创建对象后计算机才可以认识。比如想要让计算机认识洗衣机,就需要:
1. 用户先要对现实中洗衣机实体进行抽象 --- 即在人为思想层面对洗衣机进行认识,洗衣机有什么属性,有那些功能,即对洗衣机进行抽象认知的一个过程
2. 经过 1 之后,在人的头脑中已经对洗衣机有了一个清醒的认识,只不过此时计算机还不清楚,想要让计算机识别人想象中的洗衣机,就需要人通过某种面相对象的语言( 比如: C++ Java Python ) 将洗衣机用类来进行描述,并输入到计算机中
3. 经过 2 之后,在计算机中就有了一个洗衣机类,但是洗衣机类只是站在计算机的角度对洗衣机对象进行描述的,通过洗衣机类,可以实例化出一个个具体的洗衣机对象,此时计算机才能洗衣机是什么东西。
4. 用户就可以借助计算机中洗衣机对象,来模拟现实中的洗衣机实体了。
在类和对象阶段,大家一定要体会到, 类是对某一类实体 ( 对象 ) 来进行描述的,描述该对象具有那些属性,
那些方法,描述完成后就形成了一种新的自定义类型,才用该自定义类型就可以实例化具体的对象

 以上即为本期全部内容,希望大家可以有所收获

如有错误,还请指正

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

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

相关文章

学成在线笔记+踩坑(12)——用户认证

导航&#xff1a; 【黑马Java笔记踩坑汇总】JavaSEJavaWebSSMSpringBoot瑞吉外卖SpringCloud黑马旅游谷粒商城学成在线牛客面试题 目录 1 需求分析 2 【认证模块】连接用户中心数据库 2.1 连接数据库认证 2.1.1 分析 2.1.2 实现&#xff0c;实现UserDetailsService接口 …

Golang每日一练(leetDay0064) 轮转数组、颠倒二进制位

目录 189. 轮转数组 Rotate Array &#x1f31f;&#x1f31f; 190. 颠倒二进制位 Reverse Bits &#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 189. 轮转数组 Rotate Ar…

小曾同学【五周年创作纪念日】——努力向前冲的菜鸟

&#x1f604;作者简介&#xff1a; 小曾同学.com,一个致力于测试开发的博主⛽️&#xff0c; 如果文章知识点有错误的地方&#xff0c;还请大家指正&#xff0c;让我们一起学习&#xff0c;一起进步。&#x1f60a; 座右铭&#xff1a;不想当开发的测试&#xff0c;不是一个好…

什么是UA?常见蜘蛛UA?怎么查询UA?

什么是UA? UA简介查看自己的UA修改它的常见用处搜索引擎蜘蛛UA大全常见蜘蛛UA标识 UA简介 UA其实是User Agent的简称。 所谓的User Agent其实就是浏览器在跟服务器通信的时候&#xff0c;一段百十来个字符的落款信息罢了。浏览器发送的每一个HTTP请求数据的头部都加了这个信息…

【C++】红黑树的插入分析及验证

文章目录 1. 红黑树概念2. 红黑树性质3. 结构定义关于默认节点为红/黑色的讨论 4. insert情况1—— uncle节点存在且为红色(g p c左斜形成一条直线)情况2——uncle节点不存在/存在且为黑色(g p c 左斜形成直线 右单旋)uncle节点不存在uncle节点存在并且为黑色 情况3——uncle节…

第7章链接:编译器驱动程序

示例程序由两个源文件组成&#xff0c;main.c 和 swap.c。 main函数初始化一个两元素的整数数组&#xff0c;然后调用swap函数来交换这一对数。 main.c void swap();int buf[2] {1, 2};int main() {swap();return 0; }swap.c extern int buf[];int *bufp0 &buf[0]; i…

【Java】Java中线程安全有哪些实现思路?

文章目录 1、使用 synchronized 关键字2、使用 ReentrantLock 类3、使用 ConcurrentHashMap 类4、使用 Atomic 类5、使用 ThreadLocal 类总结 在 Java 多线程编程中&#xff0c;线程安全是一个非常重要的概念。 线程安全通常指程序在多线程并发执行时&#xff0c;仍然能够保持正…

迄今为止,最强ChatGPT写论文技巧,总共6步,手把手告诉你

目录 第一步&#xff1a;现象确认 第三步&#xff1a;定位优质学术资源 第四步&#xff1a;对比分析 第五步&#xff1a;深挖启示 & 第六步&#xff1a;写论文 代写论文&#xff0c;不知道有多少朋友听说过&#xff0c;这是一门严格来说有点小众&#xff0c;但盈利空间…

常见问题解答:如何有效使用 Facebook 商务管理平台(BM)?

Facebook 商务管理平台&#xff08;BM&#xff09;是一个功能强大的工具&#xff0c;可帮助广告主在 Facebook 平台上管理和优化广告投放。然而&#xff0c;对于初次接触 BM 的用户来说&#xff0c;可能会遇到一些问题和困惑。本文将回答一些常见问题&#xff0c;帮助您更有效地…

如何使用分布式存储系统促进 AI 模型训练

在处理小型数据集和简单算法时&#xff0c;传统的机器学习模型可以存储在独立机器或本地硬盘驱动器上。然而&#xff0c;随着深度学习的发展&#xff0c;团队在处理更大的数据集和更复杂的算法时越来越多地遇到存储瓶颈。 这凸显了分布式存储在人工智能&#xff08;AI&#xf…

半监督学习笔记

聚类假设 假设输入数据点形成簇&#xff0c;每个簇对应于一个输出类&#xff0c;那么如果点在同一个簇中&#xff0c;则它们可以认为属于同一类。聚类假设也可以被视为低密度分离假设&#xff0c;即&#xff1a;给定的决策边界位于低密度地区。两个假设之间的关系很容易看出。一…

C++ 智能指针的原理、分类、使用

1. 智能指针介绍 为解决裸指针可能导致的内存泄漏问题。如&#xff1a; a&#xff09;忘记释放内存&#xff1b; b&#xff09;程序提前退出导致资源释放代码未执行到。 就出现了智能指针&#xff0c;能够做到资源的自动释放。 2. 智能指针的原理和简单实现 2.1 智能指针的原…

讯飞星火 VS 文心一言:谁是中文大语言模型的TOP1?

在百度发布文心一言一个多月后&#xff0c;科大讯飞也发布了自己的大模型“讯飞星火大模型”。本篇博客就测评一下这两个在中文圈最受好评的大语言模型&#xff0c;顺便辅以ChatGPT为参考。大家一起来看看到底谁是中文大语言模型的TOP1&#xff1f; 目录 体验网址 1、旅游攻…

Class类文件的结构

1 class文件介绍 Class文件是一组以8个字节为基础单位的二进制流&#xff1b; 各个数据项目严格按照顺序紧凑地排列在文件之中&#xff0c;中间没有添加任何分隔符; 采用一种类似C语言结构体的伪结构来存储数据&#xff0c;只要两种数据类型&#xff1a;“无符号数”和“表”…

execl函数总结以及扩展

为什么要用exec族函数&#xff0c;有什么作用&#xff1f; (1)一个父进程希望复制自己&#xff0c;使父、子进程同时执行不同的代码段。这在网络服务进程中是常见的一一父进程等待客户端的服务请求。当这种请求到达时&#xff0c;父进程调用fork&#xff0c;使子进程处理此请求…

移动机器人运动规划---基于图搜索的基础知识---图和图搜索算法的基本概念

移动机器人运动规划---基于图搜索的基础知识---图和图搜索算法的基本概念 图和图搜索算法的基本概念图的基础概念图搜索基本概念图搜索算法图搜索算法框架 图和图搜索算法的基本概念 图的基础概念 图是有节点和边的一种表达方式 各节点由边连起来 边可以是有向的&#xff0c;…

Java经典笔试题—day07

Java经典笔试题—day07 &#x1f50e;选择题&#x1f50e;编程题&#x1f95d;Fibonacci数列&#x1f95d;合法括号序列判断 &#x1f50e;结尾 &#x1f50e;选择题 (1)Java属于&#xff08; &#xff09; A.操作系统 B.办公软件 C.数据库系统 D.计算机语言 D (2)类声明中&a…

大数据Doris(十八):Properties配置项和关于ENGINE

文章目录 Properties配置项和关于ENGINE 一、Properties配置项 二、关于ENGINE Properties配置项和关于ENGINE 一、Properties配置项 在创建表时,可以指定properties设置表属性,目前支持以下属性: replica

Kali-linux系统指纹识别

现在一些便携式计算机操作系统使用指纹识别来验证密码进行登录。指纹识别是识别系统的一个典型模式&#xff0c;包括指纹图像获取、处理、特征提取和对等模块。如果要做渗透测试&#xff0c;需要了解要渗透测试的操作系统的类型才可以。本节将介绍使用Nmap工具测试正在运行的主…

前端面试题汇总大全 -- 持续更新!

文章目录 一、html 系列 ⭐⭐⭐⭐⭐1、H5新增特性和css3新增特性&#xff1f;2、什么是HTML5&#xff0c;以及和HTML的区别是什么&#xff1f;3、说说你对 Dom 树的理解&#xff1f;4、跨域时怎么处理 cookie&#xff1f;5、说说你对 SSG 的理解&#xff1f;6、从输入url&#…