C++----类与对象(下篇)

再谈构造函数

回顾函数体内赋值

在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值。

class Date{ 
public: 
	Date(int year, int month, int day) { 
		_year = year; 
		_month = month; 
		_day = day; 
	} 

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

注意:虽然上述构造函数调用之后,对象中已经有了一个初始值,但是不能将其称为对对象中成员变量的初始化, 构造函数体中的语句只能将其称为赋初值,而不能称作初始化。因为初始化只能初始化一次,而构造函数体内可以多次赋值

初始化列表

格式

以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括号中的初始值或表达式。

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成员变量 、自定义类型成员(且该类没有默认构造函数时)

为什么呢?

首先,当类的对象实例化时,会调用构造函数,如果有对成员变量赋值的操作,就会对成员变量进行赋值。引用成员变量、const成员变量必须在定义的时候初始化,不能再进行赋值操作,因为引用必须初始化,且当一个引用一旦引用了一个实体,就不能通过赋值操作再引用实体;而const 成员变量的值一旦被设定就不能通过赋值操作改变。

class B{ 
public: 
	//正确写法:
	//初始化列表:对象成员变量定义的位置,符合初始化只能初始化一次的要求。
	B(int a, int ref):_ref(ref),_n(10) 
	{}
			
	//错误写法:
	B(int a, int ref) {
		//这里并不是对象成员变量定义的位置,是函数体内赋值,对成员变量赋值的地方。
		_ref=ref;
		_n=a;
	} 
			
private: 
	//这里只是成员变量声明的地方,不是定义的地方。
	int& _ref; // 引用 
	const int _n; // const 
}; 
		
int main(){
	// 对象实例化
	B bb1(10, 1); 
	B bb2(11, 2);
	return 0;
}

对于自定义类型成员变量_aobj,如果它有默认构造函数,那么可以不显式地在初始化列表中初始化它,编译器会自动调用默认构造函数。如果没有默认构造函数,则必须在初始化列表中显式调用其构造函数。

A 有默认构造函数:

class A {
public:
    A(int a = 0) : _a(a) {}

private:
    int _a;
};

class B {
public:
    // A 有默认构造函数,所以可以不显式初始化 _aobj
    B(int a, int ref) : _ref(ref), _n(10) {}

private:
    A _aobj; // 有默认构造函数
    int& _ref; // 引用
    const int _n; // const
};

A 没有默认构造函数:

class A {
public:
    A(int a) : _a(a) {}

private:
    int _a;
};

class B {
public:
    // 在初始化列表中显式调用 A 的构造函数
    B(int a, int ref) : _aobj(a), _ref(ref), _n(10) {}

private:
    A _aobj; // 无默认构造函数
    int& _ref; // 引用
    const int _n; // const
};

对于内置类型(如 int),如果初始化列表中没有显式初始化,则使用缺省值(如果有的话)或者未定义值(如果没有缺省值)。如果初始化列表中显式初始化了内置类型成员,则使用指定的值。

class B {
public:
    // 写法1:_x 未在初始化列表中显式初始化,使用缺省值 1
    B(int a, int ref) : _ref(ref), _n(10) {}

    // 写法2:_x 在初始化列表中显式初始化为 2
    B(int a, int ref, int x) : _ref(ref), _n(10), _x(2) {}

private:
    int& _ref; // 引用
    const int _n; // const
    int _x = 1; // 缺省值为 1,但仅在未显式初始化时使用
};
3.尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量,一定会先使用初始化列表初始化。

我们先来看一个代码:

typedef int DataType;
class Stack {
public:
    Stack(size_t capacity = 10) {
        _array = (DataType*)malloc(capacity * sizeof(DataType));
        if (nullptr == _array) {
            perror("malloc 申请空间失败");
            return; 
        }

        _size = 0;
        _capacity = capacity;
    }

    // ... 其他成员函数

private:
    DataType* _array;
    size_t _size;
    size_t _capacity;
};

class MyQueue {
public:
    MyQueue() {} 
    MyQueue(int capacity) {}

private:
    Stack _pushst;
    Stack _popst;
};

int main()
{
	MyQueue q1;//这里的q1._pushst和q1._popst成员变量的capacity都是10。
		
	return 0;
}

即使在MyQueue类中的构造函数里什么操作都没有,我们也没有写初始化列表,当MyQueue类实例化对象时调用到MyQueue构造函数了,也会调用到_pushst和_popst成员变量的构造函数,因为MyQueue类中所有的成员变量还是会走初始化列表。但是如果我们显示化地写处初始化成员列表,它就会走我们写的显示化的初始化成员列表,这样我们就可以根据自己的需求设置_pushst和_popst成员变量的容量大小了(_capacity):

class MyQueue {
public:
    // 默认构造函数,不显式初始化_pushst和_popst,它们将使用Stack的默认构造函数(capacity为10)
    MyQueue() {}
    
    // 有参构造函数,使用初始化列表显式初始化_pushst和_popst的capacity
    MyQueue(int capacity) : _pushst(capacity), _popst(capacity) {}
    
private:
    Stack _pushst; 
    Stack _popst;  
};

int main() {
    MyQueue q1; // 使用默认构造函数,q1._pushst和q1._popst的capacity都是10
    MyQueue q2(100); // 使用有参构造函数,q2._pushst和q2._popst的capacity都是100
    
    return 0;
}

4.用初始化列表动态分配空间
class Stack{
public:
	Stack(int capacity = 10)
		: _a((int*)malloc(capacity * sizeof(int)))
		,_top(0)
		,_capacity(capacity)
    	{
	    	if (nullptr == _a)
			{
				perror("malloc申请空间失败");
				exit(-1);
			}
			
			// 要求数组初始化一下
			memset(_a, 0, sizeof(int) * capacity);
		}
private:
	int* _a;
	int _top;
	int _capacity;
};
5.成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关。

我们来看这样的代码:

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(); 

    return 0;
} 

 最后它会输出什么呢?答案:1 随机值

因为它先声明的是_a2,所以初始化列表中也会先声明_a2。但此时_a1还没有被赋值(所以是随机值),所以_a2会被赋值为随机值。然后再初始化_a1,把a赋给_a1,所以_a1就是1了,所以最后会输出1 随机值。

所以建议声明的顺序和定义的顺序保持一致。

explicit关键字

我们来看这样的代码:

#include <iostream>
using namespace std;

class A {
public:
    A(int a) : _a(a) {
        cout << "A(int a)" << endl;
    }

    A(const A& aa) : _a(aa._a) {
        cout << "A(const A& aa)" << endl;
    }

private:
    int _a;
};

int main() {
    A aa1(1);  // 直接调用构造函数 A(int a)
    A aa2 = 2; // 隐式类型转换:2 转换为 A 的临时对象,然后拷贝构造 aa2

    // 注意:以下代码会导致编译错误,因为不能从 int 直接转换为 A&
    // A& aa3 = 2; // error C2440: “初始化”: 无法从“int”转换为“A &”

    // 但是,可以转换为 const A&,因为临时对象具有常性
    const A& aa3 = 2; // 隐式类型转换:2 转换为 A 的临时对象,然后绑定到 const A& aa3

    return 0;
}

在这个例子中,A aa2 = 2; 发生了隐式类型转换,2 被用来构造一个 A 类型的临时对象,然后这个临时对象通过拷贝构造函数来初始化 aa2。然而,在同一个表达式里出现连续构造时,现代编译器通常基本都会有这样的优化。

如果我们不想要这样的隐式转换发生该怎么办呢?

在初始化列表前面加一个expilicit就可以了:

#include <iostream>
using namespace std;

class A {
public:
    explicit A(int a) : _a(a) {
        cout << "A(int a)" << endl;
    }

    A(const A& aa) : _a(aa._a) {
        cout << "A(const A& aa)" << endl;
    }

private:
    int _a;
};

int main() {
    A aa1(1);  // 直接调用构造函数 A(int a)

    // 下面的代码会报错,因为 explicit 禁止了隐式类型转换
    // A aa2 = 2; // error C2440: “初始化”: 无法从“int”转换为“const A &”

    // 同样,即使绑定到 const A&,隐式类型转换也被禁止
    // const A& aa3 = 2; // error C2440: “初始化”: 无法从“int”转换为“const A &”

    // 正确的做法是显式调用构造函数
    A aa2(2);  // 直接调用构造函数 A(int a)
    const A& aa3 = A(2); // 显式创建临时对象并绑定到 const A&

    return 0;
}

static成员

概念

声明为 static 的类成员称为类的静态成员。用 static 修饰的成员变量称为静态成员变量;用 static 修饰的成员函数称为静态成员函数。

特性

1.静态成员也是类的成员,受public、protected、private 访问限定符的限制

2.静态成员为所有类对象所共享,不属于某个具体的对象,存放在静态区。

class A{
public:
	A(){
		++_scount;
	}
		
	A(const A& t) {
		++_scount;
	}
		
	~A(){ 
		--_scount;
	}
		
private:
	// 成员变量 -- 属于每个一个类对象,存储对象里面
	int _a1 = 1;
	int _a2 = 2;
		
	// 静态成员变量 -- 属于类,属于类的每个对象共享,存储在静态区,生命周期是全局的
	static int _scount;
};

3. 静态成员变量必须在类外定义,定义时不添加static关键字,类中只是声明。静态成员变量不能通过缺省值初始化,因为静态成员没有初始化列表

class A{
public:
	A(){
		++_scount;
	}
		
	A(const A& t) {
		++_scount;
	}
		
	~A(){ 
		--_scount;
	}
		
private:
	// 成员变量 -- 属于每个一个类对象,存储对象里面
	int _a1 = 1;
	int _a2 = 2;
		
	// 静态成员变量 -- 属于类,属于类的每个对象共享,存储在静态区,生命周期是全局的
	static int _scount;
    // 静态成员变量不能通过缺省值初始化,因为静态成员没有初始化列表
    // static int _scount = 0; //错误做法
};

4. 类静态成员即可用 类名::静态成员 或者 对象.静态成员 来访问 ,但是要注意一些问题:

虽然可以通过对象访问静态成员,但一般不推荐这样做,因为静态成员不属于任何对象。此外,如果静态成员是私有的,则不能直接从类或对象外部访问它,需要通过公有成员函数来访问。

代码例子(错误示范)

int main() {
    // _scount 是私有的
    // 下面的代码会报错,不能突破私有权限访问静态成员变量
    cout << A::_scount << endl;
    A a;
    cout << a::_scount << endl;

    return 0;
}

正确访问方式

class A {
public:
    static int GetCount() {
        return _scount;
    }

private:
    static int _scount;
};

int A::_scount = 0;

int main() {
    A a;
    cout << "Count: " << A::GetCount() << endl; // 正确访问
    cout << "Count: " << a.GetCount() << endl;  // 也可以通过对象访问,但不推荐
    return 0;
}

5. 静态成员函数没有隐藏的this指针,不能访问任何非静态成员 ,但是非静态成员函数可以调用类的静态成员函数。

class A {
public:
    static int GetCount() {
        // 不能访问非静态成员
        // _a1++; // 错误
        return _scount;
    }

    void NonStaticFunc() {
        // 非静态成员函数可以调用静态成员函数
        GetCount();
    }

private:
    int _a1 = 1;
    static int _scount;
};

int A::_scount = 0;

int main() {
    A a;
    a.NonStaticFunc(); // 调用非静态成员函数,内部调用静态成员函数
    return 0;
}

友元

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

友元函数

前面我们讲过流插入和流提取运算符的重载,就用到了友元C++----类与对象(中篇)-CSDN博客

友元类

友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。
  • 友元关系是单向的,不具有交换性:比如Time类中声明Date类为其友元类,那么可以在Date类中直接访问Time类的私有成员变量,但想在Time类中访问Date类中私有的成员变量则不行。
  • 友元关系不能传递:如果BA的友元,CB的友元,则不能说明CA的友元。
  • 友元关系不能继承,在继承位置再给大家详细介绍。
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;
};

内部类

概念

如果一个类定义在另一个类的内部,这个内部类就叫做内部类 。内部类是一个独立的类,它不属于外部类,更不能通过外部类的对象去访问内部类的成员。外部类对内部类没有任何优越的访问权限。

注意

内部类就是外部类的友元类(参见友元类的定义),内部类可以通过外部类的对象参数来访问外部类中的所有成员。但是外部类不是内部类的友元,不可以直接访问内部类的私有属性的成员。

特性

1. 内部类可以定义在外部类的publicprotectedprivate

2. 注意内部类可以直接访问外部类中的static成员,不需要外部类的对象/类名。

class A{
private:
    static int k;
    int h;
public:
    class B // B天生就是A的友元
    {
        public:
        void foo(const A& a)
        {
            cout << k << endl;//OK:直接访问外部类的静态成员变量
            cout << a.h << endl;//OK
        }
    };
};

int A::k = 1;

int main()
{
    A::B b;//实例化内部类B对象的写法
    b.foo(A());
 
    return 0;
}

3. sizeof(外部类)=外部类,和内部类没有任何关系。

class A{
private:
    static int k;
    int h;
public:
    class B // B天生就是A的友元
    {
        public:
        void foo(const A& a)
        {
            cout << k << endl;//OK:直接访问外部类的静态成员变量
            cout << a.h << endl;//OK
        }
    };
};

int A::k = 1;

int main()
{
    cout << sizeof(A) <<endl;
 
    return 0;
}

最终结果会输出4,我们来分析一下:

首先,需要明确的是,sizeof(A)所计算的是类A的实例在内存中所占的大小,而非类A本身作为一个类型的大小。在类A中,static int k 是一个静态成员变量。静态成员变量是属于类的,而不是类的实例的。因此,它不会占用类实例的内存空间。所有类的实例共享同一个静态成员变量的值。int h; 是一个非静态成员变量。它属于类的每个实例,并且会占用内存空间。BA的一个嵌套类,但是它没有存在外部类A中,也没有在外部类A中创建内部类的对象,所以也不会增加A的实例的大小。唯一占用空间的是h,它是一个int类型,占用4个字节。

匿名对象

概念

匿名对象是在表达式中临时创建的对象,没有名字,通常用于简化代码或直接在需要对象的地方进行一次性使用。

class A{
public:
    A(int a = 0)
        :_a(a)
    {
        cout << "A(int a)" << endl;
    }
	
    ~A()
    {
        cout << "~A()" << endl;
    }
private:
    int _a;
};

int main(){
    A aa(1);  // 有名对象
    A(2);     // 匿名对象

    return 0;
}

特征

1.调用成员函数的格式

#include<iostream>
using namespace std;

class Solution {
public:
    int Sum_Solution(int n) {
        cout << "Sum_Solution" << endl;
        //...
        return n;
    }
};

int main(){
    Solution sl;
    sl.Sum_Solution(10);//有名对象调用函数的写法

    Solution().Sum_Solution(20);//匿名对象调用函数的写法

    return 0;
}

2.即用即销毁

class A{
public:
    A(int a = 0)
        :_a(a)
    {
        cout << "A(int a)" << endl;
    }
	
    ~A()
    {
        cout << "~A()" << endl;
    }
private:
    int _a;
};

int main(){
    A aa(1);  // 有名对象--有名对象的生命周期在当前函数局部域
    A(2);     // 匿名对象--匿名对象的生命周期在所在当前行的表达式

    return 0;
}

3.匿名对象具有常性

#include<iostream>
using namespace std;

class A{
public:
    A(int a = 0)
        :_a(a)
    {
        cout << "A(int a)" << endl;
    }
	
    ~A()
    {
        cout << "~A()" << endl;
    }
private:
    int _a;
};

int main(){
    A aa(1);  // 有名对象 -- 生命周期在当前函数局部域
    A(2);     // 匿名对象 -- 生命周期在所在当前行的表达式

    //A& ra = A(1);  // 错误写法
    const A& ra = A(1); //正确写法:匿名对象具有常性

    return 0;
}

4.const引用可以延长匿名对象的生命周期

对于上一段代码,也许你会觉得,由于匿名对象的生命周期在当前行的表达式,所以ra在下一行就有变成类似于“野引用”的风险。但是const引用可以延长匿名对象的生命周期,生命周期延长至在当前函数局部域。

#include<iostream>
using namespace std;

class A{
public:
    A(int a = 0)
        :_a(a)
    {
        cout << "A(int a)" << endl;
    }
	
    ~A()
    {
        cout << "~A()" << endl;
    }
private:
    int _a;
};

int main(){
    A aa(1);  // 有名对象 -- 生命周期在当前函数局部域
    A(2);     // 匿名对象 -- 生命周期在所在当前行的表达式

    const A& ra = A(1); // const引用延长匿名对象的生命周期,生命周期在当前函数局部域
    A(10);

    return 0;
}

应用:C++ 编译器优化

在C++中,编译器会对临时对象的构造和拷贝进行优化,以减少不必要的开销。

以该代码为例:

#include<iostream>
using namespace std;

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

    A(const A& aa)
        :_a(aa._a)
    {
        cout << "A(const A& aa)" << endl;
    }

    A& operator=(const A& aa)
    {
        cout << "A& operator=(const A& aa)" << endl;

        if (this != &aa)
        {
            _a = aa._a;
        }

        return *this;
    }

    ~A()
    {
        cout << "~A()" << endl;
    }
private:
    int _a;
};

void Func1(A aa)
{

}

A Func2() {
    A aa; // 构造一个A对象
    return aa; // 返回值优化:一般会调用拷贝构造
}

1. 拷贝构造+拷贝构造——>一次构造(返回值优化)

当函数返回一个对象时,编译器可能会优化掉返回过程中的拷贝构造,直接构造返回的对象在目标位置。

int main() {
    cout << "在同一行同一个表达式时:" << endl;
    A ra1 = Func2(); // 拷贝构造+拷贝构造 ->优化为拷贝构造
    // 输出可能只显示一次构造和一次析构

    cout << "不在同一行同一个表达式时:" << endl;
    A a1;
    a1 = Func2();

    return 0;
}

输出:

2. 构造+拷贝构造——>优化为一次构造

在同一行或同一个表达式中,如果发生构造和拷贝构造,编译器可能会优化为只进行一次构造。

int main() {
    cout << "不会优化,因为aa1是一个已存在的对象,需要被拷贝到Func1的参数中:" << endl;
    A aa1;
    Func1(aa1);  

    // 但是:
    cout << "构造+拷贝构造 -> 优化为构造(临时对象直接构造在Func1的参数位置):" << endl;
    Func1(A(1));  
    cout << "同上,构造一个A对象时,可能会直接构造在Func1的参数位置:" << endl;
    Func1(1);    
    
    cout << "构造+拷贝构造 -> 优化为构造(直接构造aa2):" << endl;
    A aa2 = 1;  


    return 0;
}

输出:

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

delve调试环境搭建—golang

原文地址&#xff1a;delve调试环境搭建—golang – 无敌牛 欢迎参观我的个人博客&#xff1a;无敌牛 – 技术/著作/典籍/分享等 由于平时不用 IDE 开发环境&#xff0c;习惯在 linux终端vim 环境下开发&#xff0c;所以找了golang的调试工具&#xff0c;delve类似gdb的调试界…

Oracle安装报错:将配置数据上载到资料档案库时出错

环境&#xff1a;联想服务器 windows2022安装Oracle11g 结论&#xff1a;禁用多余网卡先试试&#xff0c;谢谢。 以下是问题描述和处理过程&#xff1a; 网上处理方式: hosts文件添加如下&#xff1a; 关闭防火墙 暂时无法测试通过。 发现ping不是本地状态&#xff0c;而是…

数据结构:栈(顺序栈)

目录 1.栈的定义 2.栈的结构 3.栈的接口 3.1初始化 3.2栈的销毁 3.3压栈 3.4判断栈是否为空 3.5出栈 3.6得到栈顶元素 3.7栈的大小 1.栈的定义 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端…

LightGBM分类算法在医疗数据挖掘中的深度探索与应用创新(上)

一、引言 1.1 医疗数据挖掘的重要性与挑战 在当今数字化医疗时代,医疗数据呈爆炸式增长,这些数据蕴含着丰富的信息,对医疗决策具有极为重要的意义。通过对医疗数据的深入挖掘,可以发现潜在的疾病模式、治疗效果关联以及患者的健康风险因素,从而为精准医疗、个性化治疗方…

【WPS安装】WPS编译错误总结:WPS编译失败+仅编译成功ungrib等

WPS编译错误总结&#xff1a;WPS编译失败仅编译成功ungrib等 WPS编译过程问题1&#xff1a;WPS编译失败错误1&#xff1a;gfortran: error: unrecognized command-line option ‘-convert’; did you mean ‘-fconvert’?解决方案 问题2&#xff1a;WPS编译三个exe文件只出现u…

深入理解Redis

1.数据结构类型 数据结构-SDS-简单动态字符串 Redis构建了一种新字符串结构,称为简单动态字符串(Simple Dynamic String),简称SDS。 Redis未直接使用C语言的字符串,如:char* s = "hello",本质是字符数组: {h, e, l, l, o, \0}。因为C语言字符串存在很多问题…

前端开发 之 12个鼠标交互特效上【附完整源码】

前端开发 之 12个鼠标交互特效上【附完整源码】 文章目录 前端开发 之 12个鼠标交互特效上【附完整源码】一&#xff1a;彩色空心爱心滑动特效1.效果展示2.HTML完整代码 二&#xff1a;彩色实心爱心滑动特效1.效果展示2.HTML完整代码 三&#xff1a;粒子连结特效1.效果展示2.HT…

解析mysqlbinlog

一、前置设置 ps -ef | grep mysql 查看mysql进程对应的安装目录 需设置mysql binlog日志模式为 ROW 二、执行命令 [rootlocalhost bin]# mysqlbinlog --verbose --base64-outputdecode-rows /usr/local/mysql/data/binlog.000069 > 1.sql 查看文件具体内容

理解神经网络

神经网络是一种模拟人类大脑工作方式的计算模型&#xff0c;是深度学习和机器学习领域的基础。 基本原理 神经网络的基本原理是模拟人脑神经系统的功能&#xff0c;通过多个节点&#xff08;也叫神经元&#xff09;的连接和计算&#xff0c;实现非线性模型的组合和输出。每个…

基于Vue.js和SpringBoot的笔记记录分享网站的设计与实现(文末附源码)

博主介绍&#xff1a;✌全网粉丝50W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术范围&#xff1a;SpringBoot、Vue、SSM、HLM…

信息安全管理与评估赛题第9套

全国职业院校技能大赛 高等职业教育组 信息安全管理与评估 赛题九 模块一 网络平台搭建与设备安全防护 1 赛项时间 共计180分钟。 2 赛项信息 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 第一阶段 网络平台搭建与设备安全防护 任务1 网络平台搭建 XX:XX- XX:XX 50 任务2…

怎么在idea中创建springboot项目

最近想系统学习下springboot&#xff0c;尝试一下全栈路线 从零开始&#xff0c;下面将叙述下如何创建项目 环境 首先确保自己环境没问题 jdkMavenidea 创建springboot项目 1.打开idea&#xff0c;选择file->New->Project 2.选择Spring Initializr->设置JDK->…

【计算机视觉基础CV-图像分类】05 - 深入解析ResNet与GoogLeNet:从基础理论到实际应用

引言 在上一篇文章中&#xff0c;我们详细介绍了ResNet与GoogLeNet的网络结构、设计理念及其在图像分类中的应用。本文将继续深入探讨如何在实际项目中应用这些模型&#xff0c;特别是如何保存训练好的模型、加载模型以及使用模型进行新图像的预测。通过这些步骤&#xff0c;读…

【CDN】快速了解CDN是什么?以及工作原理和应用场景

快速了解CDN是什么&#xff1f;以及工作原理和应用场景 一、什么是CDN&#xff1f;CDN相关的术语解释 二、CDN工作原理三、CDN与传统网站的区别四、CDN的作用和意义五、CDN的应用场景 一、什么是CDN&#xff1f; CDN英文全称Content Delivery Network&#xff0c;中文翻译即为内…

leetcode 2295.替换数组中的元素

1.题目要求: 2.题目代码: class Solution { public:vector<int> arrayChange(vector<int>& nums, vector<vector<int>>& operations){map<int,int> element_index;//创建图存入元素和元素对应的下标for(int i 0;i < nums.size()…

clickhouse-题库

1、clickhouse介绍以及架构 clickhouse一个分布式列式存储数据库&#xff0c;主要用于在线分析查询 2、列式存储和行式存储有什么区别&#xff1f; 行式存储&#xff1a; 1&#xff09;、数据是按行存储的 2&#xff09;、没有建立索引的查询消耗很大的IO 3&#xff09;、建…

记录一个SVR学习

1、为什么使用jupter来做数据预测&#xff1f;而不是传统pycharm编辑器 1、Jupyter Notebook 通过anaconda统一管理环境&#xff0c;可以运行python、R、Sql等数据分析常用语言。 2、做到交互式运行&#xff0c;可以逐步运行代码块&#xff0c;实时查看结果&#xff0c;便于调…

【WRF教程第3.2期】预处理系统 WPS详解:以4.5版本为例

预处理系统 WPS 详解&#xff1a;以4.5版本为例 WPS 嵌套域&#xff08;WPS Nested Domains&#xff09;USGS 和 MODIS 土地利用重力波拖拽方案静态数据&#xff08;Gravity Wave Drag Scheme Static Data&#xff09;1. 什么是重力波拖拽方案&#xff08;GWDO&#xff09;静态…

Stealthy Attack on Large Language Model based Recommendation

传统RS依赖id信息进行推荐&#xff0c;攻击&#xff1a;生成虚假用户&#xff0c;这些用户对特定目标物体给于高评价&#xff0c;从而影响模型的训练。 基于llm的RS&#xff1a;llm利用语义理解&#xff0c;将用户兴趣转化为语义向量&#xff0c;通过计算用户兴趣向量与物品向…

Pytorch | 从零构建EfficientNet对CIFAR10进行分类

Pytorch | 从零构建EfficientNet对CIFAR10进行分类 CIFAR10数据集EfficientNet设计理念网络结构性能特点应用领域发展和改进 EfficientNet结构代码详解结构代码代码详解MBConv 类初始化方法前向传播 forward 方法 EfficientNet 类初始化方法前向传播 forward 方法 训练过程和测…