当前位置: 首页 > news >正文

Day 14 C++ 对象的初始化和清理

目录

为什么要进行对象的初始化和清理

构造函数和析构函数

构造函数(Constructor)

构造函数语法

调用时机

构造函数的调用方式

括号法

显式法

隐式转换法

构造函数分类

分类方式

按参数分为有参构造和无参构造

按类型分为普通构造和拷贝构造

默认构造函数(Default Constructor)

定义

编译器生成的默认构造函数和析构函数

默认构造函数(Default Constructor)

合成析构函数(Synthesized Destructor)

注意

带参数的构造函数(Parameterized Constructor)

拷贝构造函数(Copy Constructor)

定义

被调用情况

使用一个已经创建完毕的对象来初始化一个新对象

值传递的方式给函数参数传值

以值方式返回局部对象

构造函数调用规则

析构函数(Destructor)

定义

语法

被自动调用情况

注意

示例

初始化列表(initializer list)

定义

语法

示例

优点

深拷贝与浅拷贝

浅拷贝(Shallow Copy)

深拷贝(Deep Copy)

分析

注意

类对象作为类成员

示例

构造和析构的顺序  

构造函数的执行顺序是按照成员变量在类中声明的顺序进行的

析构函数的执行顺序与构造函数相反

举例

 总结

静态成员(Static Members)

静态成员可以包括静态变量和静态函数两种形式

静态变量(Static Variables)

定义

 特点

示例

 静态函数(Static Functions)

定义

特点

 示例

 静态成员变量访问方式

1.通过实例化一个对象,通过对象访问静态成员

2.通过类名

格式: 类型 类::静态成员

作用域解析运算符(scope resolution operator)


为什么要进行对象的初始化和清理

对象的初始化和清理是确保程序安全性的重要环节。

对象没有正确初始化可能导致未定义的行为,包括访问未初始化的成员变量、调用未初始化的指针等。这些问题往往会导致程序崩溃、内存泄漏或者产生错误的计算结果。因此,在使用对象或变量之前,应该始终确保它们已经被正确地初始化。

另一方面,对象的清理也同样重要。如果一个对象占用了资源(如分配了内存、打开了文件等),在不再需要该对象时,及时清理这些资源非常重要。否则,就会造成资源泄漏,导致内存泄漏或文件句柄泄漏等问题,从而浪费系统资源并可能影响系统的稳定性和性能

通过正确地初始化和清理对象,可以提高程序的安全性、稳定性和可维护性。

构造函数和析构函数

  • 构造函数:主要作用在于创建对象时为对象的成员属性赋值,构造函数由编译器自动调用,无须手动调用。

  • 析构函数:主要作用在于对象销毁前系统自动调用,执行一些清理工作。

C++利用了构造函数析构函数进行对象的初始化和清理 ,这两个函数将会被编译器自动调用,完成对象初始化和清理工作。

对象的初始化和清理工作是编译器强制要我们做的事情,因此如果我们没有显式地提供构造函数和析构函数,编译器会提供默认的构造函数和析构函数,并进行空实现。这些默认的构造函数和析构函数被称为合成构造函数(Synthesized Constructors)和合成析构函数(Synthesized Destructors)。

构造函数(Constructor)

构造函数语法

类名(){}

  1. 没有返回值也不写void

  2. 是在创建对象时被调用的特殊成员函数,用于初始化对象的数据成员。

  3. 函数名称与类名相同

  4. 构造函数可以有参数,因此可以发生重载

  5. 程序在调用对象时候会自动调用构造,无须手动调用,而且只会调用一次(初始化操作)

 

调用时机

构造函数在对象创建时自动调用,它可以执行各种初始化操作,例如给对象的数据成员赋初值、分配动态内存、打开文件等。构造函数不需要手动调用,而是在以下情况下自动调用:

  • 当创建一个对象时,使用new运算符创建动态对象时会调用构造函数。
  • 当定义一个局部对象时,在对象定义处会自动调用构造函数。
  • 当一个对象作为函数参数进行传递时,函数的形参会调用拷贝构造函数来初始化。

构造函数的调用方式

 

括号法

通过在创建对象时使用圆括号,传递相应的参数来调用构造函数。

MyClass obj(arg1, arg2);

显式法

通过使用关键字explicit显式调用构造函数。这种方式可以防止隐式类型转换。

MyClass obj = MyClass(arg1, arg2);

隐式转换法

当需要创建对象并且存在类型转换时,编译器可以自动进行隐式类型转换并调用合适的构造函数。

MyClass obj = arg;

其中arg是不同类型的对象或基本数据类型,编译器会根据需要调用构造函数进行类型转换并创建新的对象。

构造函数分类

 

分类方式

 

按参数分为有参构造和无参构造

1.有参构造函数带有参数,用于接收外部传入的值来初始化对象的成员变量;

2.无参构造函数没有参数,可以使用默认值或者对成员变量进行默认初始化。

按类型分为普通构造和拷贝构造

1.普通构造函数用于创建新的对象,并根据传入的参数来初始化对象的成员变量;

2.拷贝构造函数用于使用一个已存在的对象来创建一个新对象,将已有对象的值复制给新对象的成员变量。

默认构造函数(Default Constructor)

定义

没有参数的构造函数被称为默认构造函数。当对象被创建时,如果没有提供任何参数,就会调用默认构造函数。默认构造函数可以用来初始化对象的数据成员为默认值。如果我们没有定义构造函数,编译器会提供一个空实现的默认构造函数。

 

编译器生成的默认构造函数和析构函数
默认构造函数(Default Constructor)

如果没有显式定义构造函数,编译器会自动生成一个空参数的默认构造函数。默认构造函数不执行任何操作,只是将对象的成员变量初始化为默认值(例如数值类型为0,指针类型为nullptr,类类型使用默认构造函数进行初始化)。

合成析构函数(Synthesized Destructor)

如果没有显式定义析构函数,编译器会自动生成一个析构函数。合成析构函数会按照成员变量声明的逆序,自动调用每个成员变量的析构函数,并在函数体中执行一些清理工作(例如释放内存、关闭文件等)。对于类类型的成员变量,会递归调用其析构函数。

 

注意

当我们显式定义了构造函数或析构函数时,编译器就不会再提供默认的构造函数或析构函数了。因此,在某些情况下,我们可能需要显式定义构造函数或析构函数,以满足特定的需求。

 

带参数的构造函数(Parameterized Constructor)

带有参数的构造函数可以接受一定数量和类型的参数,用来初始化对象的数据成员。通过传递参数给构造函数,我们可以在创建对象时将特定的值赋给对象的数据成员。

 

 

拷贝构造函数(Copy Constructor)

定义

拷贝构造函数用于创建一个新对象,并将现有对象的值复制到新对象中。它的参数是同一类的另一个对象的引用。拷贝构造函数通常用于对象的复制和初始化过程,例如通过赋值、函数传参或返回值返回对象时的复制操作。

 

被调用情况
使用一个已经创建完毕的对象来初始化一个新对象

当使用一个已存在的对象来创建一个新对象时,拷贝构造函数会被调用。这包括通过直接赋值、作为函数参数传递、或者作为函数返回值返回等方式。

值传递的方式给函数参数传值

当一个对象作为函数参数以值传递的方式传递时,编译器会调用拷贝构造函数来创建函数内部的副本。

以值方式返回局部对象

当函数返回一个对象的副本时,拷贝构造函数会被调用。这通常发生在函数返回一个局部对象的情况下。

构造函数调用规则

默认情况下,c++编译器至少给一个类添加3个函数

1.默认构造函数(无参,函数体为空)

2.默认析构函数(无参,函数体为空)

3.默认拷贝构造函数,对属性进行值拷贝

构造函数调用规则如下:

  • 如果用户定义有参构造函数,c++不在提供默认无参构造,但是会提供默认拷贝构造

  • 如果用户定义拷贝构造函数,c++不会再提供其他构造函数

析构函数(Destructor)

定义

析构函数是在对象被销毁时自动调用的特殊成员函数。它的主要作用是在对象生命周期结束时执行清理工作,例如释放动态分配的内存、关闭文件或释放其他资源。

 

语法

~类名(){}

  1. 析构函数,没有返回值也不写void

  2. 函数名称与类名相同,在名称前加上符号 ~

  3. 析构函数不可以有参数,因此不可以发生重载

  4. 程序在对象销毁前会自动调用析构,无须手动调用,而且只会调用一次

被自动调用情况

  1. 当对象的作用域结束时,例如当一个对象是局部变量,它的作用域结束后会自动调用析构函数。

  2. 使用delete关键字手动释放通过new操作符分配的内存时,会调用对象的析构函数。

  3. 在容器(如数组、容器类)中的对象被删除时(如调用erase()),会自动调用对象的析构函数。

 

注意

当对象是通过new创建的,并存储在堆上时,必须手动调用delete运算符来显式调用析构函数,以避免内存泄漏。

示例

#include <iostream>
using namespace std;class Person {
public:// 无参(默认)构造函数Person() {cout << "无参构造函数!" << endl;}// 有参构造函数Person(int a) {age = a;cout << "有参构造函数,年龄为" << age << "岁!" << endl;}// 拷贝构造函数Person(const Person& p) {age = p.age;cout << "拷贝构造函数,复制了一个" << age << "岁的对象!" << endl;}// 析构函数~Person() {cout << "析构函数!" << endl;}public:int age;
};// 调用无参构造函数
void test01() {Person p; // 调用无参构造函数
}// 调用有参的构造函数和拷贝构造函数
void test02() {// 括号法Person p1(20);// 显式法Person p2 = Person(30);Person p3 = Person(p2);// 隐式转换法Person p4 = 40;Person p5 = p4;Person p6(p4);
}int main() {test01();test02();return 0;
}

这段代码实现了一个简单的示例,展示了构造函数的使用和调用方式。下面是对代码的解释:

  1. 定义了一个名为 Person 的类,在类中声明了一个公有成员变量 age 和三个构造函数:无参构造函数、有参构造函数和拷贝构造函数。

  2. 在无参构造函数中,输出 "无参构造函数!" 的信息。

  3. 在有参构造函数中,根据传入的参数初始化 age 成员变量,并输出 "有参构造函数,年龄为X岁!" 的信息(其中 X 是传入的参数值)。

  4. 在拷贝构造函数中,通过将传入对象的 age 成员变量赋值给当前对象的 age 成员变量,创建了一个新的对象,并输出 "拷贝构造函数,复制了一个X岁的对象!" 的信息(其中 X 是传入对象的 age 值)。

  5. 定义了 test01 函数,它用于测试无参构造函数的调用。在该函数中,创建一个 Person 对象 p,这将调用无参构造函数并输出相应信息。

  6. 定义了 test02 函数,它用于测试有参构造函数和拷贝构造函数的不同调用方式。

  • 对于括号法,使用 Person p1(20) 创建一个带有整数参数的 Person 对象,调用有参构造函数,并输出相应信息。
  • 对于显式法,使用 Person p2 = Person(30) 显式地调用有参构造函数创建对象 p2,同时在创建过程中输出相应信息。同样地,使用 Person p3 = Person(p2) 显式地调用拷贝构造函数创建对象 p3,并输出相应信息。
  • 对于隐式转换法,使用 Person p4 = 40 隐式地调用有参构造函数创建对象 p4,并输出相应信息。然后使用 Person p5 = p4 隐式地调用拷贝构造函数创建对象 p5,并输出相应信息。此外,还可以使用拷贝构造函数直接将一个已存在的对象传递给构造函数来创建新的对象,例如 Person p6(p4)

主函数 main 中调用了 test01 和 test02 函数,使得这些函数被执行并观察输出结果。 

初始化列表(initializer list)

定义

初始化列表是一种在 C++ 中用于初始化类成员变量的语法。通过初始化列表,可以在创建对象时直接为成员变量赋初值。

语法

构造函数():属性1(值1),属性2(值2)... {}

 具体来说,初始化列表使用冒号(:)紧跟在构造函数的声明后面,并在列表中指定成员变量的初始值。构造函数体内部可以进行其他操作,但初始化列表在构造函数体执行之前完成。

示例

class MyClass {
private:int number;double value;
public:// 构造函数,使用初始化列表初始化成员变量MyClass(int n, double v) : number(n), value(v) {// 构造函数体// 可以在这里进行其他操作}// ...
};

在上面的示例中,MyClass 类有两个私有成员变量 numbervalue。构造函数使用初始化列表来分别初始化这两个成员变量。在构造函数的参数列表后面的冒号后,number(n) 表示将参数 n 的值赋给成员变量 numbervalue(v) 表示将参数 v 的值赋给成员变量 value。在构造函数的主体部分中,还可以进行其他操作。

可以用无参构造函数,但是n,v 必须是具体的

MyClass() : number(1), value(1.0){}

优点

  1. 提供了一种更直观、简洁的方法来初始化成员变量。
  2. 可以避免成员变量的默认初始化,直接使用指定的初值。
  3. 对于常量成员变量或引用类型的成员变量,必须使用初始化列表进行初始化,因为它们只能在创建对象时初始化一次。

 

深拷贝与浅拷贝

 

浅拷贝(Shallow Copy)

简单的赋值拷贝操作

当进行浅拷贝时,仅拷贝对象或数据的地址引用,而不会创建新的内存空间。这意味着原对象和拷贝对象将共享同一块内存空间。如果其中一个对象修改了这块内存中的数据,另一个对象也会受到影响。

 

深拷贝(Deep Copy)

在堆区重新申请空间,进行拷贝操作

当进行深拷贝时,会创建一个新的内存空间,并将原对象的所有内容复制到新的内存空间中。这样,拷贝对象将有自己独立的内存空间,对其进行修改不会影响到原对象

 

分析

浅拷贝只复制了对象的引用,而没有复制对象的内容。因此,原对象和拷贝对象指向同一块内存空间。这种情况下,如果修改了拷贝对象的内容,原对象也会受到影响。常见的浅拷贝方式包括默认拷贝构造函数、赋值运算符等

而深拷贝则完全复制了对象的内容,包括对象所引用的其他对象。这样,在拷贝对象中修改数据不会影响到原始对象,因为它们拥有各自独立的内存空间。要实现深拷贝,通常需要自定义拷贝构造函数或赋值运算符,确保深层次的数据也被复制到新的内存空间中。

 

注意

在某些情况下,特别是当对象包含动态分配的内存(例如指针、数组等)时,使用浅拷贝可能会导致问题。因为多个对象共享相同的内存,释放内存的时候可能会导致重复释放或悬空指针等问题。这时,深拷贝是一种更安全可靠的选择。

在执行深拷贝时,如果对象涉及到其他对象的引用,还需要对这些引用的对象进行递归深拷贝,以确保所有相关数据都被正确地复制。

在 C++ 中,默认情况下,类的拷贝构造函数和赋值运算符是浅拷贝的。如果需要进行深拷贝,可以自定义拷贝构造函数和赋值运算符,或者使用智能指针等工具来管理内存,确保对象复制的正确性和安全性。

 

 

类对象作为类成员

在 C++ 中,一个类可以作为另一个类的成员变量。这种情况下,我们称该成员为 对象成员 

 

示例

class Address {
private:std::string street;std::string city;
public:Address(const std::string& s, const std::string& c) : street(s), city(c) {}// ...
};class Person {
private:std::string name;int age;Address address; // Address 类对象作为 Person 类的成员
public:Person(const std::string& n, int a, const Address& addr) : name(n), age(a), address(addr) {}// ...
};

在上面的示例中,有两个类:AddressPersonAddress 类表示地址,包含街道和城市两个成员变量。Person 类表示人员信息,包含姓名、年龄和一个 Address 类对象作为成员变量。

Person 类的构造函数中,使用初始化列表初始化 nameageaddress 成员变量。对于 address 成员变量,传入一个 Address 类对象作为参数,用于初始化它。通过这种方式,每个 Person 对象都包含一个独立的 Address 对象,作为其一部分。

构造和析构的顺序  

构造函数的执行顺序是按照成员变量在类中声明的顺序进行的

先构造基类的成员变量,然后构造派生类的成员变量。如果一个类作为另一个类的成员对象,那么它将在包含它的类的构造函数中构造。

析构函数的执行顺序与构造函数相反

也就是说,先调用派生类的析构函数,然后调用基类的析构函数。同时,在一个类的析构函数中,成员变量的析构顺序与构造函数中的初始化顺序相反。

举例

class Base {
public:Base() { std::cout << "Base constructor" << std::endl; }~Base() { std::cout << "Base destructor" << std::endl; }
};class Derived : public Base {
public:Derived() { std::cout << "Derived constructor" << std::endl; }~Derived() { std::cout << "Derived destructor" << std::endl; }
};class MyClass {
private:Base base;Derived derived;
public:MyClass() { std::cout << "MyClass constructor" << std::endl; }~MyClass() { std::cout << "MyClass destructor" << std::endl; }
};
Base constructor
Derived constructor
MyClass constructor
MyClass destructor
Derived destructor
Base destructor

 可以看到,构造函数的调用顺序是先构造 Base 的成员变量,然后是 Derived 的成员变量,最后是 MyClass 的构造函数。而析构函数的调用顺序则相反,先调用 MyClass 的析构函数,然后是 Derived 的析构函数,最后是 Base 的析构函数。

 总结

先调用对象成员的构造,再调用本类构造,析构函数相反

静态成员(Static Members)

在C++中,静态成员是属于类本身的,而不是类的实例。它们与类相关联,而不是与类的对象相关联。静态成员在所有类对象之间共享,只有一个副本存在于内存中。

静态成员可以包括静态变量和静态函数两种形式

静态变量(Static Variables)

定义

静态变量是在类声明中用关键字 static 声明的成员变量。它们在所有类对象之间共享相同的存储空间,并且可以在没有任何类对象实例的情况下访问。静态变量可以用于跨对象共享数据或用作计数器等。

 特点

 

  • 所有对象共享同一份数据

  • 在编译阶段分配内存

  • 类内声明,类外初始化

示例
class MyClass {
public:static int count;  // 静态变量声明
};int MyClass::count = 0;  // 静态变量的定义和初始化int main() {MyClass::count++;  // 访问和修改静态变量return 0;
}

 

 静态函数(Static Functions)

定义

静态函数是在类声明中用关键字 static 声明的成员函数。它们不依赖于类的任何实例,可以直接通过类名访问。静态函数不能访问非静态成员变量,也不能调用非静态成员函数,因为它们没有隐式的 this 指针。

 

特点
  • 所有对象共享同一个函数

  • 静态成员函数只能访问静态成员变量

 

 

 示例
class MathUtils {
public:static int add(int a, int b) {  // 静态函数声明return a + b;}
};int result = MathUtils::add(3, 4);  // 调用静态函数

 静态成员变量访问方式

1.通过实例化一个对象,通过对象访问静态成员

Person p1;
p1.m_A = 100;

2.通过类名

格式: 类型 类::静态成员
int Person::m_A = 10;

作用域解析运算符(scope resolution operator)

在C++中,:: 运算符被称为作用域解析运算符(scope resolution operator)。它的主要作用是访问类、命名空间、结构体等作用域内的成员。具体来说,在类成员函数或类外部定义成员函数时可以使用 :: 运算符来指定要定义的函数属于哪个类的成员函数。总之,:: 运算符允许我们在特定的作用域中访问成员,并指定所操作的对象或类。

 

ps:整理了足足一个上午,累麻了 

相关文章:

Day 14 C++ 对象的初始化和清理

目录 为什么要进行对象的初始化和清理 构造函数和析构函数 构造函数&#xff08;Constructor&#xff09; 构造函数语法 调用时机 构造函数的调用方式 括号法 显式法 隐式转换法 构造函数分类 分类方式 按参数分为有参构造和无参构造 按类型分为普通构造和拷贝构造…...

Delphi7最佳登录窗体设计

Delphi7我们这里用登录窗体来做演示。输入正确用户名和密码后&#xff0c;登录窗体释放&#xff0c;显示主窗体。 方法/步骤 1.打开Delphi7集成开发环境&#xff0c;在默认工程的Form1窗体放置一个Label1控件&#xff0c;拖动控件边界调整大小&#xff0c;并将Object Inspect…...

动脑学院Jetpack Compose学习笔记

最近b站学习了一下Compose相关内容&#xff0c;整理了相关笔记&#xff0c;仅供大家参考。 资源链接如下&#xff0c;象征性收取1个积分 https://download.csdn.net/download/juliantem/88125198...

Qt中线程的使用

Qt中线程的使用 在qt中线程的使用有两种方式&#xff0c;第一种就是创建一个类继承QObject类&#xff0c;之后使用moveToThread函数将线程添加到类中。另一种就是创建一个类继承QThread类&#xff0c;在类中实现run函数。 第一种方式&#xff1a; 1、首先创建一个自定义的类…...

基于YOLOv8开发构建蝴蝶目标检测识别系统

在前面的一篇博文中已经很详细地描述了如何基于YOLOv8开发构建自己的个性化目标检测模型&#xff0c;感兴趣的话可以看下&#xff1a; 《基于YOLOv8开发构建目标检测模型超详细教程【以焊缝质量检测数据场景为例】》 本文的主要目的就是基于YOLOv8来开发构建细粒度的蝴蝶目标…...

【已解决】电脑连上网线但无法上网

文章目录 案例情况解决方案必要的解决方法简要概括详细步骤1、打开控制面板2、打开更改适配器设置3、 找Internet协议版本44、修改配置 可能有用的解决方法 问题解决原理Internet 协议版本 4&#xff08;TCP/IPv4&#xff09;确保IP地址和DNS服务器设置为自动获取 案例情况 网…...

Linux 学习记录57(ARM篇)

Linux 学习记录57(ARM篇) 本文目录 Linux 学习记录57(ARM篇)一、外部中断1. 概念2. 流程图框 二、相关寄存器1. GIC CPU Interface (GICC)2. GIC distributor (GICD)3. EXTI registers 三、EXTI 寄存器1. 概述2. 内部框图3. 寄存器功能描述4. EXTI选择框图5. EXTI_EXTICR1 &…...

Doris注意事项,Doris部署在阿里云,写不进去数据

1.Doris官网 Doris官网https://doris.apache.org/ 2.根本原因 本地idea访问FE&#xff0c;FE会返回BE的地址&#xff0c;但是在服务器上通过ip addr查看&#xff0c;发现只有局域网IP&#xff0c;所以FE返回了局域网的IP&#xff0c;导致idea连接不上BE 3.解决办法 重写Ba…...

502 Bad GateWay报错的解决方法

什么是502 bad gateway 报错 简单来说 502 是报错类型代码 bad gateway 错误的网关。是Web服务器作为网关或代理服务器时收到无效的响应。 用我们的口语说就是运行网站的服务器暂时挂了(不响应)。 产生错误的原因 1.连接超时 我们向服务器发送请求 由于服务器当前链接太多&am…...

openpnp - ReferenceStripFeeder 改版零件

文章目录 openpnp - ReferenceStripFeeder 改版零件概述笔记整体效果散料飞达主体磁铁仓盖板飞达编带中间压条飞达编带两边压条装配体用的8mm编带模型END openpnp - ReferenceStripFeeder 改版零件 概述 官方推荐了ReferenceStripFeeder的模型smd_strip_feeders_mod_tray.zip…...

VoxPoser:使用大语言模型(GPT-4)来对机器人操作的可组合三维值图【论文解读】

这是最近斯坦福的李飞飞团队的一篇论文:VoxPoser: Composable 3D Value Maps for Robotic Manipulation with Language Models 主要是通过大语言模型LLM和视觉语言模型VLM结合&#xff0c;来对机器人做各种日常操作&#xff0c;我们可以先来看下实际效果&#xff1a;大语言模型…...

RISC-V公测平台发布 · 第一个WEB Server “Hello RISC-V world!”

RISC-V公测平台Web Server地址&#xff1a;http://175.8.161.253:8081 一、前言 Web Server是互联网应用的基础设施&#xff0c;无论是用户访问网站&#xff0c;还是后端服务提供商和开发者构建各种应用程序&#xff0c;Web Server都在其中扮演着至关重要的角色。 显而易见…...

Linux 发行版 CentOS 于 Ubuntu 软件的安装、卸载、查找

CentOS于Ubuntu 内核都是Linux&#xff0c;是一样的。 CentOS 软件格式 .rpm sudo yum [-y] [ install | remove | search ] 软件名称 install 安装 remove 移除 search 搜索 Ubuntu 软件格式 .deb sudo apt [-y] [ install | remove | search ] 软件名称 install 安装 remove…...

cmd相关操作命令

1.根据端口号查询对应进程的PID netstat -ano | findstr 端口号 例如&#xff1a;netstat -ano | findstr 9080&#xff1b;该端口所属进程的PID为6684 2.根据PID查询对应进程 tasklist | findstr PID 例如&#xff1a;tasklist | findstr 6684&#xff1b;该PID所属进程名为…...

使用EM算法完成聚类任务

EM算法&#xff08;Expectation-Maximization Algorithm&#xff09;是一种基于迭代优化的聚类算法&#xff0c;用于在无监督的情况下将数据集分成几个不同的组或簇。EM算法是一种迭代算法&#xff0c;包含两个主要步骤&#xff1a;期望步骤&#xff08;E-step&#xff09;和最…...

❤️创意网页:创意视觉效果粒子循环的网页动画

✨博主&#xff1a;命运之光 &#x1f338;专栏&#xff1a;Python星辰秘典 &#x1f433;专栏&#xff1a;web开发&#xff08;简单好用又好看&#xff09; ❤️专栏&#xff1a;Java经典程序设计 ☀️博主的其他文章&#xff1a;点击进入博主的主页 前言&#xff1a;欢迎踏入…...

【MTI 6.S081 Lab】thread

【MTI 6.S081 Lab】thread 前言调度Uthread: switching between threads (moderate)实验任务Hints解决方案thread_switchthread_create()thread_schedule() Using threads (moderate)实验任务解决方案 Barrier (moderate)实验任务解决方案 本实验前去看《操作系统导论》第29章基…...

AWS / VPC 云流量监控

由于安全性、数据现代化、增长、灵活性和成本等原因促使更多企业迁移到云&#xff0c;将数据存储在本地的组织正在使用云来存储其重要数据。亚马逊网络服务&#xff08;AWS&#xff09;仍然是最受追捧和需求的服务之一&#xff0c;而亚马逊虚拟私有云&#xff08;VPC&#xff0…...

【C++学习笔记】extern “c“以及如何查看符号表

如何查看符号表 要查看.a文件的内容&#xff0c;可以使用ar命令。下面是一些常见的用法&#xff1a; 列出.a文件中包含的所有文件&#xff1a; ar t <filename.a>提取.a文件中的单个文件&#xff1a; ar x <filename.a> <filename.o>将.a文件中的所有文件提…...

24考研数据结构-数组和特殊矩阵

目录 数据结构&#xff1a;数组与特殊矩阵数组数组的特点数组的用途 特殊矩阵对角矩阵上三角矩阵和下三角矩阵稀疏矩阵特殊矩阵的用途 结论 3.4 数组和特殊矩阵3.4.1数组的存储结构3.4.2普通矩阵的存储3.4.3特殊矩阵的存储1. 对称矩阵(方阵)2. 三角矩阵(方阵)3. 三对角矩阵(方阵…...

服务器后台运行程序

代码运行 要让代码在服务器后台运行&#xff0c;有多种方法。在 Linux 系统中&#xff0c;最常见的有以下几种方式&#xff1a; **1. 使用 & 符号&#xff1a;** 在命令后面添加 & 符号可以让程序在后台运行。例如&#xff1a; bash python myscript.py &但是…...

大数据课程D7——hadoop的YARN

文章作者邮箱&#xff1a;yugongshiyesina.cn 地址&#xff1a;广东惠州 ▲ 本章节目的 ⚪ 了解YARN的概念和结构&#xff1b; ⚪ 掌握YARN的资源调度流程&#xff1b; ⚪ 了解Hadoop支持的资源调度器&#xff1a;FIFO、Capacity、Fair&#xff1b; ⚪ 掌握YA…...

Rust vs Go:常用语法对比(十三)

题图来自 Go vs. Rust: The Ultimate Performance Battle 241. Yield priority to other threads Explicitly decrease the priority of the current process, so that other execution threads have a better chance to execute now. Then resume normal execution and call f…...

【【51单片机DA转换模块】】

爆改直流电机&#xff0c;DA转换器 main.c #include <REGX52.H> #include "Delay.h" #include "Timer0.h"sbit DAP2^1;unsigned char Counter,Compare; //计数值和比较值&#xff0c;用于输出PWM unsigned char i;void main() {Timer0_Init();whil…...

[SQL挖掘机] - 字符串函数 - substring

介绍: substring函数是在mysql中用于提取字符串的一种函数。它接受一个字符串作为输入&#xff0c;并返回从该字符串中指定位置开始的一部分子串。substring函数可以用于获取字符串中的特定字符或子串&#xff0c;以便进行进一步的处理或分析。 用法: 下面是substring函数的…...

第一百一十六天学习记录:C++提高:STL-string(黑马教学视频)

string基本概念 string是C风格的字符串&#xff0c;而string本质上是一个类 string和char区别 1、char是一个指针 2、string是一个类&#xff0c;类内部封装了char*&#xff0c;管理这个字符串&#xff0c;是一个char型的容器。 特点&#xff1a; string类内部封装了很多成员方…...

Meta-Transformer 多模态学习的统一框架

Meta-Transformer是一个用于多模态学习的新框架&#xff0c;用来处理和关联来自多种模态的信息&#xff0c;如自然语言、图像、点云、音频、视频、时间序列和表格数据&#xff0c;虽然各种数据之间存在固有的差距&#xff0c;但是Meta-Transformer利用冻结编码器从共享标记空间…...

tinkerCAD案例:24.Tinkercad 中的自定义字体

tinkerCAD案例&#xff1a;24.Tinkercad 中的自定义字体 原文 Tinkercad Projects Tinkercad has a fun shape in the Shape Generators section that allows you to upload your own font in SVG format and use it in your designs. I’ve used it for a variety of desi…...

list与流迭代器stream_iterator

运行代码&#xff1a; //list与流迭代器 #include"std_lib_facilities.h" //声明Item类 struct Item {string name;int iid;double value;Item():name(" "),iid(0),value(0.0){}Item(string ss,int ii,double vv):name(ss),iid(ii),value(vv){}friend ist…...

九耶:冯·诺伊曼体系

冯诺伊曼体系&#xff08;Von Neumann architecture&#xff09;是一种计算机体系结构&#xff0c;它由匈牙利数学家冯诺伊曼于1945年提出。冯诺伊曼体系是现代计算机体系结构的基础&#xff0c;几乎所有的通用计算机都采用了这种体系结构。 冯诺伊曼体系的核心思想是将计算机硬…...

行业网站建设运营/福州seo服务

平时开发报表时&#xff0c;经常用到小计、总计之类分类汇总功能&#xff0c;在使用SSRS之前&#xff0c;常常使用SQL语句通过拼凑实现&#xff0c;不仅开发效率低&#xff0c;维护起来也很不方便。在SSRS 2008 中&#xff0c;就可以通过“分组”功能&#xff0c;方便的实现“分…...

他达拉非片正确服用方法/搜索引擎优化包括哪些内容

tooltip样式主要通过formatter设置&#xff0c;官网明确指出支持字符串模板和回调函数两种形式。 1.字符串模板 举例&#xff1a; tooltip: {trigger: item,formatter: {a} <br/>{b} : {c} ({d}%),confine: true},结果如下图所示&#xff1a; 2.回调函数 回调函数 支…...

ui一般用什么软件做/seo教程视频论坛

jQuery鼠标换轮滚动事件1、鼠标混轮滚动事件2、添加class属性3、实现屏幕滚动效果css代码部分html与javascript部分1、鼠标混轮滚动事件 代码如下所示&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8">…...

小说网站怎么做词/情感营销的十大案例

二叉树的后序遍历 题目描述&#xff1a;给定一个二叉树&#xff0c;返回它的 后序 遍历。 示例说明请见LeetCode官网。 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;https://leetcode-cn.com/problems/binary-tree-postorder-traversal/ 著作权归领…...

公司网站能否申请国外免费空间/关键词搜索优化外包

请用C实现一个链表&#xff0c;实现链表的查找&#xff0c;逆置&#xff0c;替换&#xff0c;删除&#xff0c;添加&#xff0c;清空&#xff0c;创建。查找、替换和删除、添加里面都会用到遍历链表的操作&#xff0c;所以重点在于遍历&#xff0c; 链表的逆置和清空考虑到效率…...

wordpress更新慢/百度在线翻译

计算机VB基础知识---知识导学VB基础知识---知识导学Viscal Basic语言一.算法1.定义&#xff1a;算法(Algorithm)就是解决某一类问题的方法和步骤。2.算法的五个重要特征&#xff1a;(1)输入&#xff1a;可以是0个或多个输入&#xff1b;算法可以没有输入。(2)输出&#xff1a;可…...