爆学C++之类和对象(上)

news2024/9/28 15:30:02

1.类的定义

类定义格式

• class为定义类的关键字,Stack为类的名字,{}中为类的主体,注意类定义结束时后⾯分号不能省略。类体中内容称为类的成员:类中的变量称为类的属性或成员变量; 类中的函数称为类的⽅法或者成员函数。

• 为了区分成员变量,⼀般习惯上成员变量会加⼀个特殊标识,如成员变量前⾯或者后⾯加_ 或者 m开头,注意C++中这个并不是强制的,只是⼀些惯例,具体看公司的要求。

• C++中struct也可以定义类,C++兼容C中struct的⽤法,同时struct升级成了类,明显的变化是struct中可以定义函数,⼀般情况下我们还是推荐⽤class定义类。

• 定义在类⾯的成员函数默认为inline。

类和结构体最大的不同是类里面能定义函数

那么我们使用类型名+点+函数名那么我们就能调用这个函数了

如果是指针的话,那么我们用箭头就行了

类的定义--拿栈来举例:

class Stack
{
    void  Init(int n = 4)//给出一个缺省参数,缺省值默认给的是4
    {
        array = (int*)malloc(sizeof(int) * n);
        if (nullptr == array)
        {
            perror("malloc fail!");
            return;
        }
        capacity = n;
        top = 0;
    }

    void Push(int x)
    {
        //扩容
        array[top++] = x;
    }
    int Top()
    {
        assert(top > 0);
        return array[top - 1];
    }
    void Destroy()
    {
        free(array);
        array = nullptr;
        top = capacity = 0;
    }

    //栈
    int* array;
    size_t capacity;
    size_t top;
};
//类名就是类型
int main()
{
    Stack st1;//我们直接用这个类名当成类型来定义对象
    //我们初始化的话直接就是类型加点再加函数名,那么我么家就调用了这个函数
    st1.Init();
    st1.Push(1);
    st1.Push(2);
    st1.Push(3);
    st1.Push(4);

    cout << st1.Top() << endl;

    st1.Destory();
    return 0;
}

//那么我们定义完类的结构,但是我们这里为什么显示的是错的呢?
//那么多报错
//就说明我们这个类还不是完全体,那么我们就需要进行后面的学习了

访问限定符

• C++⼀种实现封装的⽅式,⽤类将对象的属性与⽅法结合在⼀块,让对象更加完善,通过访问权限选择性的将其接⼝提供给外部的⽤⼾使⽤。

• public修饰的成员在类外可以直接被访问;protected和private修饰的成员在类外不能直接被访问,protected和private是⼀样的,以后继承章节才能体现出他们的区别。

• 访问权限作⽤域从该访问限定符出现的位置开始直到下⼀个访问限定符出现时为⽌,如果后⾯没有访问限定符,作⽤域就到 }即类结束。

• class定义成员没有被访问限定符修饰时默认为private,struct默认为public。

• ⼀般成员变量都会被限制为private/protected,需要给别⼈使⽤的成员函数会放为public。

三种访问限定符

struct兼容C语言的用法,又有C++的用法

那么struct用C++的用法的时候和class有什么区别呢?

class定义成员没有被访问限定符修饰时默认为private,struct默认为public。

就是我们在使用class来定义类的话,我们没有使用访问限定符,那么这个类中默认的就是私有的

这种情况的话struct是公有的

这个就是class和struct的唯一的区别点

class默认是私有

struct默认是公有

那么学习了访问限定符之后,那么我们的类就算定义完成了

在类定义完之后我们还挖掘了struct在C/C++两个方向的不同以及struct和class的区别

类的完整定义以及struct来定义类:

class Stack
{

public:
    //成员函数
    void  Init(int n = 4)//给出一个缺省参数,缺省值默认给的是4
    {
        array = (int*)malloc(sizeof(int) * n);
        if (nullptr == array)
        {
            perror("malloc fail!");
            return;
        }
        capacity = n;
        top = 0;
    }

    void Push(int x)
    {
        //扩容
        array[top++] = x;
    }
    int Top()
    {
        assert(top > 0);
        return array[top - 1];
    }
    void Destroy()
    {
        free(array);
        array = nullptr;
        top = capacity = 0;
    }

private:
    //成员变量
    //栈
    int* array;
    size_t capacity;
    size_t top;
};

struct Person//利用结构体也定义了一个类  那么类名就是类型
{
public://公有化
    void Init(const char* name, int age, int tel)
    {
        strcpy(_name, name);//将name复制过去
        _age = age;
        _tel = tel;
    }
    void Print()
    {
        cout << "姓名:" << _name << endl;
        cout << "年龄:" << _age << endl;
        cout << "电话:" << _tel << endl;

    }

private://私有化
    char _name[10];
    int _age;
    int _tel;
};


//队列
typedef struct QueueNode
{
    struct QueueNode* next;
    int val;
}QNode;

typedef struct Queue
{
    QNode* head;
    QNode* tail;
    int size;
}QU;

void QueueInit(QU* q)
{
    q->head = nullptr;
    q->tail = nullptr;
    q->size = 0;
}
//类名就是类型
int main()
{
    Stack st1;//我们直接用这个类名当成类型来定义对象
    //我们初始化的话直接就是类型加点再加函数名,那么我么家就调用了这个函数
    st1.Init();
    st1.Push(1);
    st1.Push(2);
    st1.Push(3);
    st1.Push(4);

    cout << st1.Top() << endl;

    st1.Destroy();

    Person p1;
    p1.Init("张三",18,132);
    p1.Print();


    QU qu;
    QueueInit(&qu);

    return 0;
}

//我们在这里定义public  公有的
//直到遇到下一个访问限定符,如果没有下一个访问限定符的话
//那么这个访问限定符到};这个中间的空间都是外界能够进行访问的

//我们在函数后面加上private,那么这些函数就是公有的
//那么private到};中间的就是私有的


//一般来说的话成员函数一般是公有的
//成员的变量一般是私有的

//那么到这里我们就真正定义出了一个类

//类中有成员变量也有成员函数

//我们现在是能对类里面的的函数进行访问的,但是不能对类里面的变量成员进行访问,因为这个是我们的私有的

//我们能用struct来定义类,但是我们还是推荐用class


//那么我们通过这种队列的案例我们发现在C++中
//我们的struct既能像c语言一样用struct来定义结构体,也能像C++一样用struct来定义类


//在类里面定义成员函数默认是内联函数  前面没有加inline那么默认也加了inline


//struct兼容C语言的用法,又有C++的用法

//那么struct用C++的用法的时候和class有什么区别呢?

类域

• 类定义了⼀个新的作⽤域,类的所有成员都在类的作⽤域中,在类体外定义成员时,需要使⽤ :: 作⽤域操作符指明成员属于哪个类域。

• 类域影响的是编译的查找规则,下⾯程序中Init如果不指定类域Stack,那么编译器就把Init当成全局函数,那么编译时,找不到array等成员的声明/定义在哪⾥,就会报错。指定类域Stack,就是知道Init是成员函数,当前域找不到的array等成员,就会到类域中去查找。

我们在之前学到,C++中有四个域:局部域、全局域、命名空间域和类域

域的作用是可以作为名字的隔离

同一个域不能定义同名

不同的域能够定义同名

命名空间域和类域不会影响生命周期的,局部域和全局域是会影响生命周期的

函数声明定义分离的时候我们要指定类域:

下面我们就看看是如何使用的

以栈的初始化为例

test.cpp

#include"Stack.h"
int main()
{
    Stack st;//  类中的栈   定义一个栈
    st.Init();//栈的初始化
    return 0;
}
//这个就是标准的类的声明和定义分离
//我们在Stack.cpp文件中指定我们要查找的函数,前面带上指定的类域
//那么编译器就会到指定的类域进行搜索

//函数声明定义分离的时候我们要指定类域

Stack.cpp

#define _CRT_SECURE_NO_WARNINGS 1
#include"Stack.h"

//我们在类外面定义函数
void Stack::Init(int n )
//为了让编译器找到我们类中的函数
//我们需要在前面加上Stack::
//在前面指定类域
{
    _a = (int*)malloc(sizeof(int) * n);
    if (nullptr == _a)
    {
        perror("malloc fail!");
        return;
    }
    _capacity = n;
    top = 0;
}

Stack.h

#pragma once

#include<iostream>
#include<stdlib.h>
#include<assert.h>
using namespace std;
//类的基本结构
class Stack
{
public:
    void Init(int n = 4);//缺省参数在声明和定义都在的时候只能给声明,不能给定义

private:
    int* _a;
    int top;
    int _capacity;
};

2.实例化

实例化的概念

• ⽤类类型在物理内存中创建对象的过程,称为类实例化出对象。

• 类是对象进⾏⼀种抽象描述,是⼀个模型⼀样的东西,限定了类有哪些成员变量,这些成员变量只 是声明,没有分配空间,⽤类实例化出对象时,才会分配空间。

• ⼀个类可以实例化出多个对象,实例化出的对象 占⽤实际的物理空间,存储类成员变量。打个⽐ ⽅:类实例化出对象就像现实中使⽤建筑设计图建造出房⼦,类就像是设计图,设计图规划了有多 少个房间,房间⼤⼩功能等,但是并没有实体的建筑存在,也不能住⼈,⽤设计图修建出房⼦,房 ⼦才能住⼈。同样类就像设计图⼀样,不能存储数据,实例化出的对象分配物理内存存储数据。

#include<iostream>
using namespace std;



class Data
{
public:
    void Init(int year, int month, int day)
    {
        _year = year;
        _month = month;
        _day = day;

    }
    void Print()

    {
        cout << _year << "/" << _month << "/" << _day << endl;
    }
private:
    //声明 系统在这里没有给变量开空间,那么这里就是声明
    int _year;
    int _month;
    int _day;
};
//定义:系统在这里开了空间
//int year;

int main()
{
    Data d1;//用类型定义出了个对象,这个对象里面有年月日这些数据
    //那么这种操作就是类实例化出对象
    Data d2;
    //1个类可以实例化出n个对象

  //创建出对象之后我们就能调用类中对应的方法
  d1.Init(2024, 6, 5);
  d2.Init(2024, 9, 8);
  d1.Print();
  d2.Print();

    return 0;
}
//类里面是不能存真实数据的,我们需要先用这个类实例化出一个对象
//然后这个对象里面就能进行存数据的操作

//这个类就是一个图纸
//我们根据这个图纸进行打造对象
//然后再对对象进行操作

我们先将类的结构定义好

然后用这个类当做一个图纸来定义出了个对象出来

然后对这个对象进行数据的一些操作

但是我们的类是不能进行数据的操作的

对象大小

分析⼀下类对象中哪些成员呢?类实例化出的每个对象,都有独⽴的数据空间,所以对象中肯定包含 成员变量,那么成员函数是否包含呢?⾸先函数被编译后是⼀段指令,对象中没办法存储,这些指令 存储在⼀个单独的区域(代码段),那么对象中⾮要存储的话,只能是成员函数的指针。再分析⼀下,对 象中是否有存储指针的必要呢,Date实例化d1和d2两个对象,d1和d2都有各⾃独⽴的成员变量 year/month/_day存储各⾃的数据,但是d1和d2的成员函数Init/Print指针却是⼀样的,存储在对象 中就浪费了。如果⽤Date实例化100个对象,那么成员函数指针就重复存储100次,太浪费了。这⾥需 要再额外哆嗦⼀下,其实函数指针是不需要存储的,函数指针是⼀个地址,调⽤函数被编译成汇编指 令[call 地址],其实编译器在编译链接时,就要找到函数的地址,不是在运⾏时找,只有动态多态是在 运⾏时找,就需要存储函数地址,这个我们以后会讲解。

class Data
{
public:
    void Init(int year, int month, int day)
    {
        _year = year;
        _month = month;
        _day = day;

    }
    void Print()

    {
        cout << _year << "/" << _month << "/" << _day << endl;
    }
private:
    //声明 系统在这里没有给变量开空间,那么这里就是声明
    int _year;
    int _month;
    int _day;
};
//定义:系统在这里开了空间
//int year;

int main()
{
    Data d1;//用类型定义出了个对象,这个对象里面有年月日这些数据
    //那么这种操作就是类实例化出对象
    Data d2;
    //1个类可以实例化出n个对象
    // 
    //创建出对象之后我们就能调用类中对应的方法
    d1.Init(2024, 6, 5);
    d2.Init(2024, 9, 8);
    d1.Print();
    d2.Print();


    cout << sizeof(d1) << endl;//12
    cout << sizeof(d2) << endl;//12

    //说明类的实例化的对象里面只存了成员变量‘
    //这里的话每个变量大小都是4个字节
    //那么总大小就是12个字节

    /*
    这个的话d1和d2的数据是不一样的
    d1和d2调用的Print是一样的

    为什么我们的对象的大小仅仅是这些变量
    没有带上这些函数呢?

    因为我们调用的函数都是一个函数
    仅仅是对象中的变量的数据不同
    如果我们将这个函数的大小算进去的话
    就会显得很冗余

    函数就存在公共的区域


    总结:每个类可以有很多个对象
    对象中要存成员变量
    每个对象的成员变量的数据都不一样

    但是每个对象要使用的函数都是一样的、
    那么如果我们将这个函数的指针存在对象中那么就是冗余现象了

    这些函数都是公共的
    所以我们对象的大小仅仅包含这些成员变量


    那么我们在计算类的对象的大小的时候我们只考虑成员变量,不考虑成员函数
    */



    return 0;
}
//类里面是不能存真实数据的,我们需要先用这个类实例化出一个对象
//然后这个对象里面就能进行存数据的操作

//这个类就是一个图纸
//我们根据这个图纸进行打造对象
//然后再对对象进行操作

我们类定义出的对象的大小不包括成员函数

只包括成员变量

那么计算成员变量的大小就和C语言中求结构体的大小的规则是一样的

需要遵循内存对齐规则

• 第⼀个成员在与结构体偏移量为0的地址处。

• 其他成员变量要对⻬到某个数字(对⻬数)的整数倍的地址处。

• 注意:对⻬数=编译器默认的⼀个对⻬数与该成员⼤⼩的较⼩值。

• VS中默认的对⻬数为8

• 结构体总⼤⼩为:最⼤对⻬数(所有变量类型最⼤者与默认对⻬参数取最⼩)的整数倍。

• 如果嵌套了结构体的情况,嵌套的结构体对⻬到⾃⼰的最⼤对⻬数的整数倍处,结构体的整体⼤⼩ 就是所有最⼤对⻬数(含嵌套结构体的对⻬数)的整数倍。

对齐数是可以通过pack进行修改的 具体的操作可以参考我的文章:自定义类型--结构体

// 实例化的对象是多⼤?

class A
{
public:
    void Print()
    {
        cout << _ch << endl;
    }
private:
    char _ch;
    int _i;
};
class B
{
public:
    void Print()
    {
        //...
    }
};
class C
{};
int main()
{
    A a;
    B b;
    C c;
    cout << sizeof(a) << endl;//8
    cout << sizeof(b) << endl;//1
    cout << sizeof(c) << endl;//1
    cout << &b << endl;
    cout << &c << endl;

    return 0;
}

/*
A中起码有成员变量
但是B和C中没有成员变量
那么这种就是属于特殊情况了

没有成员变量的大小不应该是0吗?
但是我们如果是0个字节的话
那么B和C就应该没有地址的

对于没有成员变量的类呢
我们是需要进行开空间的操作
开一个字节的空间
目的是为了占位
不存储有效的数据
标识对象的存在
被迫开了一个字节的空间
表示它们存在过

*/

我们计算这个类的对象的这个大小可以参考结构体的大小的计算

上⾯的程序运⾏后,我们看到没有成员变量的B和C类对象的⼤⼩是1,为什么没有成员变量还要给1个 字节呢?因为如果⼀个字节都不给,怎么表⽰对象存在过呢!所以这⾥给1字节,纯粹是为了占位标识 对象存在。

对于没有成员变量的类呢

我们是需要进行开空间的操作

开一个字节的空间

目的是为了占位

不存储有效的数据

标识对象的存在

对象中不存储成员函数的指针

成员函数的指针在一个公共的区域

3.this指针

this指针的解释

• Date类中有Init与Print两个成员函数,函数体中没有关于不同对象的区分,那当d1调⽤Init和 Print函数时,该函数是如何知道应该访问的是d1对象还是d2对象呢?那么这⾥就要看到C++给了 ⼀个隐含的this指针解决这⾥的问题

• 编译器编译后,类的成员函数默认都会在形参第⼀个位置,增加⼀个当前类类型的指针,叫做this 指针。⽐如Date类的Init的真实原型为, void Init(Date* const this, int year, int month, int day)

• 类的成员函数中访问成员变量,本质都是通过this指针访问的,如Init函数中给year赋值, >year = year; this

• C++规定不能在实参和形参的位置显⽰的写this指针(编译时编译器会处理),但是可以在函数体内显 ⽰使⽤this指针。

解释这个隐含的this指针

class Data
{
public:
    //void Init(Data*const this ,int year, int month, int day)
    void Init(int year, int month, int day)
    {
        _year = year;
        _month = month;
        _day = day;

    }
    //void Print(Data* const this)
    void Print()

    {
        //cout << this->_year << "/" << this->_month << "/" << this->_day << endl;

        cout << _year << "/" << _month << "/" << _day << endl;
    }
private:
    //声明 系统在这里没有给变量开空间,那么这里就是声明
    int _year;
    int _month;
    int _day;
};

int main()
{
    Data d1;
    Data d2;

    d1.Init(2024, 6, 5);
    //d1.Init(&d1,2024, 6, 5);

    d2.Init(2024, 9, 8);
    //  d1.Init(&d2,2024, 6, 5);

    d1.Print();
    //d1.Print(&d1);
    d2.Print();
    //d1.Print(&d2);
    return 0;
}

/*
我们在类中定义的函数的参数其实是4个参数
有一个隐参数,是一个this指针
 而且被const修饰了
 this自己是不能进行改变的

 因为这里存在4个参数
 那么我们在调用参数的时候那么第一个参数就是传的就是对象的地址

 这个就是为什么函数在被调用的时候能进行对象的区分的原因了

 而且我们的这个类函数中的打印函数里面的代码
 类成员变量的访问本质都是通过this指针进行访问的
cout << this->_year << "/" << this->_month << "/" << this->_day << endl;

这个this指针是隐含的

我们是不需要在实参和形参内写这个this指针
编译器自己会处理的
*/

这个this指针的作用本质还是给函数传对象的地址,然后根据这个对象进行区分数据

小题目

1.下⾯程序编译运⾏结果是(C)

A、编译报错 B、运⾏崩溃 C、正常运⾏

#include<iostream>
using namespace std;
class A
{
public:
    void Print()
    {
        cout << "A::Print()" << endl;
    }
private:
    int _a;
};

int main()
{
    A* p = nullptr;
    p->Print();
    return 0;
}
//成员函数的指针是在编译时确定的,没有存在对象中,所以这里虽然写了p->
// 但是没有解引用
//空指针的错误是不会报编译错误的
//我们这里传的是空指针,函数接收的是个空指针,结果正常运行
//将p的地址传递给了this

2.下⾯程序编译运⾏结果是(B)

A、编译报错 B、运⾏崩溃 C、正常运⾏

#include<iostream>
using namespace std;
class A
{
public:
    void Print()
    {
        cout << "A::Print()" << endl;
        cout << _a << endl;
    }
private:
    int _a;
};
int main()
{
    A* p = nullptr;
    p->Print();
    return 0;
}
//这里正常将p的地址传给this指针
//因为存在this指针
//我们这里的this指针是空的
//我们在第一句的打印是没有问题的
//但是我们在第二句就会出现错误了
// 原本是下面那样的
//cout << _a << endl;
//实际是这样的
//cout <<this-> _a << endl;
//这里就会解引用
// this指针解引用访问对象中的成员变量
//但是空指针是不能进行解引用的操作的
//那么这个程序就会崩溃的

这两个题的区别就是在Print函数中是否有cout << _a << endl;

如果我们的this指针接收的是空指针的话

如果函数代码中存在打印成员变量的代码的话

多半会报错的

因为这个this指针会通过箭头隐含在代码中

这个this指针会指向这个变量进行解引用

但是这里的是空指针,空指针是不能进行解引用的操作的

所以这里是会报错的

  1. this指针存在内存哪个区域的(A)

A. 栈 B.堆 C.静态区 D.常量区 E.对象⾥⾯

this是一个隐含的形参

函数调用要建立栈帧

那么局部变量要存在栈帧中

我们的形参也要存在栈帧里面

那么这个题就是A

4.C++和C语⾔实现Stack对⽐

⾯向对象三⼤特性:封装、继承、多态,下⾯的对⽐我们可以初步了解⼀下封装。

通过下⾯两份代码对⽐,我们发现C++实现Stack形态上还是发⽣了挺多的变化,底层和逻辑上没啥变化。

• C++中数据和函数都放到了类⾥⾯,通过访问限定符进⾏了限制,不能再随意通过对象直接修改数 据,这是C++封装的⼀种体现,这个是最重要的变化。这⾥的封装的本质是⼀种更严格规范的管 理,避免出现乱访问修改的问题。当然封装不仅仅是这样的,我们后⾯还需要不断的去学习。

• C++中有⼀些相对⽅便的语法,⽐如Init给的缺省参数会⽅便很多,成员函数每次不需要传对象地 址,因为this指针隐含的传递了,⽅便了很多,使⽤类型不再需要typedef⽤类名就很⽅便

• 在我们这个C++⼊⻔阶段实现的Stack看起来变了很多,但是实质上变化不⼤。等着我们后⾯看STL 中的⽤适配器实现的Stack,⼤家再感受C++的魅⼒。

C语言的数据和方法是分离的,数据是数据,方法是方法

C++将数据和方法封装到一起,将数据和方法都封装到类里面,并且通过这个访问限定符进行管理

封装本质是一种规范的管理

C++是不能访问数据的,因为有访问限定符的存在,只能调用函数

对两种语言实现的Stack可以很清楚看出两个语言的不同之处

有点以及缺点

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

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

相关文章

IDEA中设置类和方法的注释

分两步设置&#xff1a; 第一个设置是创建类的时候自动加的注解 第二个设置是快捷键为方法增加的注解 类的时候自动加的注解设置 注释模版 #if (${PACKAGE_NAME} && ${PACKAGE_NAME} ! "")package ${PACKAGE_NAME};#end /** * Description: TODO * Auth…

IOPaint部署,在服务器Ubuntu22.04系统下——点动科技

这里写目录标题 一、ubuntu22.04基本环境配置1.1 更换清华Ubuntu镜像源1.2 更新包列表&#xff1a;2. 安装英伟达显卡驱动2.1 使用wget在命令行下载驱动包2.2 更新软件列表和安装必要软件、依赖2.2 卸载原有驱动2.3 安装驱动2.4 安装CUDA2.5 环境变量配置 二、安装miniconda环境…

2024年第九届机器人与自动化工程国际会议(ICRAE 2024)即将召开!

2024年第九届机器人与自动化工程国际会议(ICRAE 2024)将于11月15-17日在新加坡举办。ICRAE 2024会议旨在为机器人与自动化工程等领域的专家学者建立一个广泛有效的学术交流平台&#xff0c;以便让参会人员及时了解行业发展动态、掌握最新技术&#xff0c;促使我们快速、准确地解…

在scss中如何使用hover(Vue项目)

在scss中如何使用hover&#xff08;Vue项目&#xff09; 最近在Vue项目中&#xff0c;想实现在鼠标悬浮时&#xff0c;修改鼠标指向的模块样式&#xff0c;但使用的是scss&#xff0c;写法是什么样的呢&#xff1f; 效果图&#xff1a; 实现代码&#xff1a; .content {widt…

Android系统和开发--安全性和权限管理 SELinux 策略 安全架构

学习android权限知识 SElinux chmod -R 777 ./ setenforce 0 adb root su fastboot oem at-unlock-vboot adb disable-verity Android权限 Android系统是基于Linux内核构建的&#xff0c;因此它继承了Linux的权限管理机制。Android应用需要通过声明权限来访问系统的某些功能&…

使用docker compose一键部署redis服务

使用docker compose一键部署redis服务 1、创建安装目录 mkdir /data/redis/ -p && cd /data/redis2、创建docker-compose.yml文件 version: 3 services:redis:image: registry.cn-hangzhou.aliyuncs.com/xiaopangpang/redis:7.0.5container_name: redisrestart: al…

Cpython解释器下实现并发编程——多进程、多线程、协程、IO模型

一、背景知识 进程即正在执行的一个过程。进程是对正在运行的程序的一个抽象。 进程的概念起源于操作系统&#xff0c;是操作系统最核心的概念&#xff0c;也是操作系统提供的最古老也是最重要的抽象概念之一。操作系统的其他所有内容都是围绕进程的概念展开的。 一&#xff09…

专利审查信息查询

1 登录国知局 国家知识产权局 政务服务平台 (cnipa.gov.cn) 进入网上办事 2 中国及多国专利审查信息查询 3 输入条件 弹出窗口 下载。 我们学校没有授权电子申请&#xff0c;没有办法&#xff0c;得自己关注&#xff01;

MySQL-进阶篇-存储引擎

文章目录 1. MySQL 的体系结构1.1 连接层1.2 服务层1.3 存储引擎层1.4 存储层 2. 存储引擎2.1 存储引擎简介2.2 查看数据库支持的引擎2.3 指定存储引擎2.4 InnoDB 引擎2.4.1 InnoDB 的特点2.4.2 与 InnoDB 有关的磁盘文件2.4.3 InnoDB 的逻辑结构 2.5 MyISAM 引擎2.5.1 MyISAM …

虚拟机安装centos7-NAT网络模式安装

1、打开虚拟机&#xff0c;点击编辑&#xff0c;选择虚拟网络配置器 2、选择VMnet8的NAT类型 3、点击NAT设置&#xff0c;修改网关 4、点击应用及确定&#xff0c;如果你的子网IP及子网掩码没有的情况下&#xff0c;请优先设置 5、点击文件&#xff0c;选择新建虚拟机 6、选择典…

42、Python之面向对象:元类应用于定义检查、动态注入、插件注册

引言 在上一篇文章中&#xff0c;我们简单聊了一下Python中元类的概念&#xff0c;以及如何定义一个简单的元类。虽然&#xff0c;我们已经学会了定义元类&#xff0c;但是&#xff0c;相信不少刚接触Python的同学&#xff0c;大多会产生这样的疑问&#xff1a;这个不太好理解…

【Leetcode 1189 】 “气球” 的最大数量 —— 数组模拟哈希表

给你一个字符串 text&#xff0c;你需要使用 text 中的字母来拼凑尽可能多的单词 "balloon"&#xff08;气球&#xff09;。 字符串 text 中的每个字母最多只能被使用一次。请你返回最多可以拼凑出多少个单词 "balloon"。 示例 1&#xff1a; 输入&#…

YOLOv5改进 | 融合改进 | C3融合重写星辰网络之Rewrite the Stars⭐【CVPR2024】

秋招面试专栏推荐 &#xff1a;深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 &#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 专栏目录&#xff1a; 《YOLOv5入门 改…

Positional Encoding | 位置编码【详解】

文章目录 1、位置编码的2种方案2、位置编码3、公式详解 &#xff1a; 绝对位置 、 相对位置4、代码4.1 代码14.2 代码2 1、位置编码的2种方案 transformer的作者刚开始说固定的位置编码和可学习的位置编码的效果是差不多的&#xff0c;后来证明可学习的位置编码没有太大的必要&…

聊一下订单超时自动关闭的几种方式以及使用场景

订单超时自动关闭的本质其实是一种延时的功能实现&#xff0c;具体实现方式有很多种&#xff0c;但是我们方式的选择是需要结合业务场景的&#xff0c;没有更好的方案&#xff0c;只有更适合的方案&#xff0c;所以我们必须要结合自己的实际业务&#xff0c;以及业务的后续发展…

政务大数据解决方案(六)

政务大数据解决方案通过构建全面的数据集成平台&#xff0c;将来自不同政府部门和公共服务领域的多维度数据汇聚起来&#xff0c;运用先进的数据分析和人工智能技术进行深度挖掘与预测&#xff0c;从而为政府提供实时、精准的信息支持&#xff0c;优化决策流程&#xff0c;提高…

工业4.0下的防勒索病毒策略:主机加固在工控机防病毒中前行

MCK主机加固产品是一款专注于数据安全解决方案的软件&#xff0c;它在防勒索病毒和工控机防病毒方面具备一系列独特的功能和优势。 防勒索病毒方面&#xff1a; 内核级签名校验技术&#xff1a;MCK系统通过这项技术对操作系统启动及加载的所有模块进行可信认证&#xff0c;确…

电脑只有一个盘怎么分区?单盘电脑的解决方案

在现代计算机使用中&#xff0c;硬盘分区是一个重要的环节&#xff0c;它有助于我们更好地管理数据、提高系统运行效率&#xff0c;并在一定程度上保护数据的安全。 然而&#xff0c;当我们购买了一台新电脑后发现电脑里只有一个硬盘分区&#xff0c;这时候我们可能就需要对电…

Golang | Leetcode Golang题解之第349题两个数组的交集

题目&#xff1a; 题解&#xff1a; func intersection(nums1 []int, nums2 []int) (res []int) {sort.Ints(nums1)sort.Ints(nums2)for i, j : 0, 0; i < len(nums1) && j < len(nums2); {x, y : nums1[i], nums2[j]if x y {if res nil || x > res[len(re…

什么是CDN,CDN的作用是什么?

CDN CDN英文全称Content Delivery Network&#xff0c;即为内容分发网络。它是建立并覆盖在承载网之上&#xff0c;将内容存储在分布式的服务器上&#xff0c;使⽤户可以从距离较近的服务器获取所需的内容&#xff0c;从⽽减少数据传输的时间和距离&#xff0c;提⾼内容的传输…