【C++】类和对象---需掌握的功能

news2024/11/15 7:15:08

目录

  • 1.初始化列表
    • 1.1构造函数赋值
    • 1.2初始化列表
      • 格式:
      • 编译器执行的顺序:
      • 特性:
    • 1.3explicit关键字
      • 类型替换过程
      • 多参数构造函数类型替换(C++11)
  • 2.static成员
    • 编程题
  • 3.匿名对象
  • 4.友元
    • 4.1友元函数
    • 4.2友元类
  • 5.内部类
  • 6.拷贝对象时的一些编译器优化
    • 6.1传值传参
    • 6.2传值返回
  • 7.理解类和对象

1.初始化列表

1.1构造函数赋值

创建对象时,编译器会调用构造函数来为对象中的成员变量一个合适的初始值。

但不是所有的成员变量都可以在构造函数内获得初始值的,如下代码:

在这里插入图片描述
运行后给出如下错误

在这里插入图片描述

这是因为被const修饰的变量只能在定义的时候初始化,那哪里是成员变量定义的地方?

答:成员变量在初始化列表 中定义并初始化。

如下图,是我们经常写的类:

在这里插入图片描述
在类内private访问限定符下的成员变量只是成员变量的声明 ,在对象创建时(也叫定义对象)会调用类内的构造函数(默认构造函数或非默认构造函数),其中在 成员变量的定义 的位置,也叫做初始化列表 (下面会讲,现在知道这个位置即可),成员变量在这个地方定义的,如果成员变量中有被const修饰的可以在此处初始化。

了解了这些,我们在来看一下初始化列表的具体特性和功能。

1.2初始化列表

格式:

初始化列表:在构造函数(默认构造函数或非默认构造函数)下以一个冒号开始 ,接着是一个以 逗号分隔的数据成员列表 ,每个“成员变量 ”后面跟一个放在括号中的初始值或表达式

class Date
{
public:
	Date()
		:_year(1)
		,_month(1)
		,_day(1)
	{}
private:
	int _year;
	int _month;
	int _day;
};

编译器执行的顺序:

  1. 之所以在这个位置以该格式写的代码被称为初始化列表,一是因为在这里成员变量完成定义,其次是编译器在对象创建后调用构造函数也是先执行初始化列表 ,将对应的成员变量初始化后,在执行构造函数体内的代码

    如下图:

    在这里插入图片描述

  2. 如果我们没有实现初始化链表,编译器会默认实现,因为对于成员变量必须要定义,而初始化列表就是定义成员变量的,只是这样初始化后的成员变量值为随机值,需要看它的构造函数或其他函数是否为其赋值。

    但要注意,我们没有实现初始化列表,遇到被const修饰的成员函数或其他特殊的情况(下面会讲),可就运行不了了。

    结论: 尽量使用初始化列表。

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

    如下图,调换初始化列表的顺序,可以观察到,程序的执行顺序为_year_month_day与声明顺序相同。

    在这里插入图片描述

特性:

  1. 每个成员变量在初始化列表中只能出现一次

    初始化只能初始化一次,第二次就成复制了,赋值是在构造函数体内完成。

  2. 类中如果包含以下成员,必须放在初始化列表位置处初始化。

    • 引用成员变量

      引用的特点就是在定义时必须赋值。

    • const成员变量

      被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(1)
    	{}
    private:
    	A _Aobj;        //没有默认构造函数
    	int& _ref;      //引用
    	const int _n;   //const
    };
    
  3. 注意: 尽量使用初始化列表,如果不能用初始化列表初始化的成员变量,如需要开辟空间的情况等等,在构造函数体内完成即可,不要只盯着初始化列表。

拓展:

C++11中规定内置类型成员变量在类中声明时可以给默认值。

这里的默认值是缺省值,不是初始化,比方说对于被const修饰的成员变量,如果在声明时给出默认值,并在初始化列表初始化,最后以初始化列表为主,若是初始化列表没有初始化则以默认值为主

class Date
{
public:
	Date()
		: _year(1)
	{
		cout << _year << endl;
	}
private:
	const int _year;
	int _month;
	int _day;
};
class A
{
public:
	A()
	{
		cout << _year << endl;
	}
private:
	const int _year = 2;
};

int main()
{
	Date today;
	A a;

	return 0;
}

在这里插入图片描述

1.3explicit关键字

构造函数不仅可以构造与初始化对象,对于单个参数或者除第一个参数无默认值其余均有默认值的构造函数(统称:单参数默认构造函数),还具有类型替换的作用。

若不想实现这种功能,在构造函数前增加关键字explicit即可

在这里插入图片描述

类型替换过程

接下来我们一步步探索这个现象

我们先来看如下代码

int main()
{
	int a = 1;
	double b = a; //隐式类型转化

	return 0;
}

这个代码是可以运行成功的,变量a在为b赋值时,发生隐式类型转化,首先生成了一个const double类型的临时变量(临时变量有常性 ),变量a将值赋给这个临时变量,由临时变量将值赋给变量b

在这里插入图片描述

了解了临时变量的存在,在来看下面的一段代码

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

private:
	int _a;
};

int main()
{
	const A& b = 1;

	return 0;
}

在这里插入图片描述

我们看到,代码成功运行并输出,而想要为引用初始化,需要为其赋一个同类型的变量,所以const A& b = 1;中,先创建一个临时的A类型对象(临时的对象也有常性,所以引用需要使用const修饰),并使用1为其成员变量赋值,这个过程调用构造函数,接着使对象b成为零时对象的引用,证明这么做必然会产生一个临时的变量。

在这里插入图片描述

到这里类型替换的过程也就呼之欲出了,不过结果可能和大家想象的不一样。

看如下代码

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

int main()
{
	A a = 1;
	//等价于: A a(1);
    
	return 0;
}

在这里插入图片描述

按照正常的想法,通过构造函数创建一个临时对象,在通过拷贝构造函数创建对象a,而现在只调用了构造函数,这是为什么?

这是编译器帮我们做出的优化,正常的过程是构造->拷贝 = a,但C++觉得这么做有些繁琐,便取消了拷贝的过程,直接通过1来构造对象a ,等价于A a(1)

在这里插入图片描述

  • 在C++发展之初这些优化是没有的,但随着发展,编译器不断进化,开始减少很多没必要的步骤,慢慢做出优化,同时对语法的要求更高,保证优化后对编译没有影响。
  • 一般新一点的编译器会有优化,老的编译器没有。

多参数构造函数类型替换(C++11)

对于多参数的构造函数,C++98是不支持进行类型替换的,但在C++11对这一块进行拓展,支持其多参数进行这一操作。需在进行多参数替换时,使用大括号包含需要传的参数即可。如下

在这里插入图片描述

  • 注意:若不想进行替换操作,在构造函数前增加explicit关键字即可

2.static成员

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

其特性如下:

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

了解了特性我们需要注意以下几种情况:

  1. 创建类的指针对象,设置为空,它可以访问类中的静态成员和静态函数

    class A
    {
    public:
    	static void Print()
    	{
    		cout << _a << endl;
    	}
    private:
    	static int _a;
    };
    
    int A::_a = 0;
    
    int main()
    {
    	A* a = nullptr;
    	a->Print();
    
    	return 0;
    }
    

    在这里插入图片描述

    静态成员为所有类对象共享,使用空指针调用,不涉及指针自生,甚至在静态成员函数内不会有this指针,不会造成编译错误。

  2. 静态成员函数不能调用非静态成员函数

    静态成员函数内没有this指针,无法调用除静态成员外的其他成员

  3. 非静态成员函数可以调用类的静态成员函数

    静态成员是所有类对象共享,所有对象都可以调用,非静态成员内有this指针,为类对象指针,可以调用静态成员,甚至非成员函数,普通函数或其他类的成员函数都可以通过类名::静态成员的方法调用一个类的静态成员

了解了这些,我们使用静态成员来做一道编程题:

编程题

求1+2+3+…+n_

描述:

求1+2+3+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句

(A?B:C)。

数据范围: 0<<n≤200
进阶: 空间复杂度 O(1) ,时间复杂度 O(n)

示例1

输入: 5

返回值:15

示例2

输入:1

返回值:1

思路:

我们创建一个类,设置两个静态成员变量,一个sum存放所有数相加的和,一个i表示当前需要加几,编写其构造函数,使创建一次对象sum加一次i,同时使i自加1,之后创建n个这个类的对象,最后得到的sum就是总和,因为成员变量一般放在private限定符下,所以在通过创建一个静态成员函数来返回这个静态成员变量sum。

注意: 创建n个对象可以使用变长数组 类名 arr[n]new,变长数组是c99中定义的,是否可以使用取决于编译器是否支持,在牛客网中的编译器支持这一语法。

代码:

class Sum
{
public:
    Sum()
    {
        _sum += _i;
        _i++;
    }
    static int Print()
    {
        return _sum;
    }
private:
    static int _sum;
    static int _i;
};

int Sum::_sum = 0;
int Sum::_i = 1;

class Solution {
public:
    int Sum_Solution(int n) {
        Sum arr[n];
        return Sum::Print();
    }
};

3.匿名对象

我们创建对象还可以通过类名() 的方式创建,这样的对象叫匿名对象声明周期 只有被创建的哪一行,该行执行完,对应的匿名对象就会被销毁。

class A
{
public:
	A()
	{
		cout << "A()" << endl;
	}
	A(int a, int b)
		: _a(a)
		, _b(b)
	{
		cout << "A(int a, int b)" << endl;
	}
	~A()
	{
		cout << "~A()" << endl;
	}
private:
	int _a;
	int _b;
};

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

	return 0;
}

在这里插入图片描述

使用场景:

如果我们需要创建对象,但对象创建后只使用一次,那就可以用匿名对象

注意:

匿名对象具有常性 ,需要使用引用接收匿名对象时需要使用const修饰。

4.友元

友元提供了一种突破封装的方法,有时提供便利,但友元会增加耦合度,破坏了封装,所以友元不宜多用。

友元分为:友元函数友元类

4.1友元函数

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

特性:

  • 友元函数 内类对象可访问类的私有和保护成员,但它不是类的成员函数
  • 友元函数不能用const修饰
  • 友元函数 可以在类定义的任何地方声明,不受类访问限定符限制
  • 一个函数可以是多个类的友元函数
  • 友元函数的调用与普通函数的调用原理相同
class A
{
public:
	friend void test(A& a); //友元函数的声明
	A(int a,int b)
		:_a(a)
		,_b(b)
	{

	}
private:
	int _a;
	int _b;
};

void test(A& a)
{
	cout << a._a << endl;
}

int main()
{
	A a(1, 2);
	test(a);
	return 0;
}

在这里插入图片描述

4.2友元类

友元类所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。

注意:

  1. 友元关系是单向的,不具有交换性。

    在这里插入图片描述

  2. 友元关系不能传递

    如果A是B的友元,B是C的友元,则不能说明A是B的友元

    如果A是B的友元,C也是B的友元,也不能说明A和B一个是另一个的友元。

    在这里插入图片描述

  3. 友元关系不能继承

class A
{
public:
	friend class B;//友元类的声明
	A()
		: _Aa(1)
		, _Ab(2)
	{}

private:
	int _Aa;
	int _Ab;
};

class B
{
public:
	B()
		: _Ba(1)
		, _Bb(2)
	{
		A aa;
		cout << aa._Aa << " " << aa._Ab << " " << endl;
	}

private:
	int _Ba;
	int _Bb;
};

int main()
{
	B bb;

	return 0;
}

在这里插入图片描述

5.内部类

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

class A
{
public:
	A()
		: _Aa(1)
		, _Ab(2)
	{}
	class B
	{
	public:
		B()
			: _Ba(1)
			, _Bb(2)
		{
			A aa;
			cout << aa._Aa << " " << aa._Ab << " " << endl;
		}

	private:
		int _Ba;
		int _Bb;
	};

private:
	int _Aa;
	int _Ab;
    static int _Ac;
};

特性:

  1. 内部类就是外部类的友元,内部类可以通过外部类的对象参数来访问外部类中的所有成员,但外部类不是内部类的友元。

  2. 内部类可以定义在外部类的public、protected、private都是可以的

  3. 想要创建一个内部类对象,需要通过外部类指定

    int main()
    {
    	A::B bb;//创建内部类
    
    	return 0;
    }
    

    在这里插入图片描述

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

    注意:友元类不可以直接访问static成员

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

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

    在这里插入图片描述

  • 对于内部类,我们只做了解就好,在C++中很少用到内部类,而java中内部类用的倒是很多。

6.拷贝对象时的一些编译器优化

在传参和传返回值的过程中,一般编译器会做出一些优化,减少对象的拷贝,这个在一些场景下可以帮我们提高程序的运行速率。

创建如下类,通过下面这个类创建的对象进行操作,观察现象,搞清楚编译器的优化

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

在上面讲explicit关键字时,我们已经知道了类型替换的概念,知道编译器会优化一些步骤使之更加便捷,下面我们针对这一现象再来研究一下

6.1传值传参

void test1(A aa)
{}

void test3(const A& aa)
{}
    
int main()
{
	A aa1;//构造
	test1(aa1);//拷贝构造
	cout << "-----------------" << endl;
    test3(aa1);//引用传参,对象已存在无需进行构造或拷贝
	cout << "-----------------" << endl;
	test1(A(1));//匿名对象构造+拷贝构造 -> 优化为直接构造
	cout << "-----------------" << endl;
	test1(1);//隐式类型,构造+拷贝构造 -> 优化为直接构造

	return 0;
}

在这里插入图片描述

对于正常的创建对象,之后将对象传递给参数,这样的操作,虽然也进行了构造和拷贝两个步骤,但它是在两行上分别执行的,绝大多数编译器都不会在此处进行优化。(一些比较激进的编译器会这样做)

对于引用传参,因为对象已经创建好了,直接引用即可,只执行了一个构造,而且函数执行完后还可以接着使用,但注意,若传过去的对象不会改变,建议使用const修饰,防止发生变化。

对于使用匿名对象传参隐式类型替换 为对象的操作,正常来看都需要经过构造、拷贝两个步骤,形参才会被赋予数据,而经过编译器优化后省去了拷贝的步骤,直接使用初始化的值构造形参。但对象在函数执行完后就无法在使用。

6.2传值返回

A test2()
{
	A a;
	return a;
}

A test4()
{
    return A(1);
}

int main()
{
	test2();//构造+拷贝构造
	cout << "-----------------" << endl;
	A aa2 = test2();//构造+拷贝构造+拷贝构造 -> 优化为:构造 + 拷贝构造
	cout << "-----------------" << endl;
	A aa1;//构造
	aa1 = test2();//构造+拷贝构造+赋值重载
	cout << "-----------------" << endl;
    A aa3 = test4();//使用匿名对象返回,构造+拷贝+拷贝 -> 构造
	cout << "-----------------" << endl;
    
	return 0;
}

在这里插入图片描述

对于传值返回中的第16行代码,返回值由一个未定义的对象接收,意味着以返回对象为参数,调用拷贝构造函数,定义该对象,所以该行代码的执行步骤应该为:构造、拷贝、拷贝编译器对其进行优化,将原本test2中返回时需要拷贝出一个临时对象的操作,优化为直接拷贝出所接收的对象,将两个拷贝优化为一个拷贝。

在这里插入图片描述

对于第19行,因为对象以及定义,使用定义好的对象接收返回对象,这里就是赋值重载,对于赋值重载无法进行优化。

对于21行,接收匿名函数返回的对象,原本应该是匿名对象调用构造函数创建对象,之后拷贝一个临时对象,由临时对象在经过拷贝创建出所要的对象,经过编译器优化,两次拷贝都不在调用,因为匿名对象只执行一行,对象返回后就会被销毁,编译器直接使用匿名对象构造出的对象作为接收返回值的对象,所得结果相同,但过程更为简洁。

在这里插入图片描述

总结:

  • 对象传参

    尽量使用引用接收参数

  • 对象返回

    1. 接收返回值对象,尽量使用拷贝方法接收,不要使用赋值接收
    2. 函数中返回对象时,尽量返回匿名对象。

7.理解类和对象

对于现实生活中的实体,计算机是不认识的,计算机只认识二进制格式的数据。如果想要让计算机认识现实生活中的实体,用户必须通过某种面向对象的语言,对实体进行描述,然后通过编写程序,创建对象后计算机才可以认识。

比如说我们使用的手机实体,想要认识让计算机认识手机,需要经过以下步骤:

  1. 先对现实生活中手机实体进行抽象—即在人为思想层面对手机进行认识,手机有什么属性,有那些功能,即对手机进行抽象认知的一个过程。
  2. 经过1后,在人的头脑中已经对手机有了一个清醒的认识,只不过此时计算机还不清楚,想要让计算机识别人想象中的手机,就需要人通过某种面向对象的语言(如:Java、C++、Python等)将手机用类来进行描述,并输入到计算机中。
  3. 经过2后,在计算机中就有了一个手机类,但手机类只是站在计算机的角度对手机对象进行描述的,通过手机类,可以实例化出一个个具体的手机对象,此时计算机才能知道手机是什么东西。
  4. 此时用户就可以借助计算机中手机对象,来模拟现实中的手机实体了。

在类和对象阶段,大家一定要体会到:

类是对某一类实体(对象)来进行描述的,描述该对象具有那些属性,那些方法,描述完成后就形成了一种新的自定义类型,用该自定义类型就可以实例化具体的对象。

在这里插入图片描述

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

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

相关文章

linux高级命令之获取管理员权限的相关命令

获取管理员权限的相关命令学习目标能够知道切换到管理员用户的命令1. sudo命令的使用命令说明sudo -s切换到root用户&#xff0c;获取管理员权限sudo某个命令的执行需要获取管理员权限可以在执行命令前面加上sudosudo -s效果图:sudo 命令效果图:说明:如果只是某次操作需要使用管…

面向对象与面向过程编程

从语言角度来讲&#xff1a; C是面向过程编程&#xff1b; C一半是面向过程编程&#xff0c;一半是面向对象编程&#xff1b; Java是面向对象编程。 一、什么是面向对象编程与面向过程编程&#xff1f; 面向过程&#xff08;Procedure Oriented 简称 PO&#xff09;&#xff1…

云计算ACP云服务器ECS实例题库

&#x1f618;作者简介&#xff1a;一名99年软件运维应届毕业生&#xff0c;正在自学云计算课程。&#x1f44a;宣言&#xff1a;人生就是B&#xff08;birth&#xff09;和D&#xff08;death&#xff09;之间的C&#xff08;choise&#xff09;&#xff0c;做好每一个选择。&…

2.你的程序乱码了吗?

学习的动力不止于此&#xff1a; 1. 乱码 #include <QApplication> #include <QLabel> #include <QFont> int main(int argc, char *argv[]) {QApplication a(argc, argv);QLabel lb;lb.setFont(QFont("Sans Serif", 24));lb.setText(" 乱…

Linux文件隐藏属性(修改与显示):chattr和lsattr

文件除了基本的九个权限以外还有隐藏属性存在&#xff0c;这些隐藏属性对于系统有很大的帮助&#xff0c;尤其是系统安全&#xff08;Security&#xff09;上 chattr&#xff08;配置文件隐藏属性&#xff09; chattr 【-】【ASacdistu】文件或目录名称 选项与参数&#xff1a…

Visual Navigation(一):阅读三篇经典论文

文章目录前言一、Learning to Navigate in Cities Without a Map二、Unsupervised Predictive Memory in a Goal-Directed Agent三、Zero-Shot Imitation LearningImitation Learning:前言 研究生不读论文还是不行的呀&#xff0c;在这里结合下别人的总结等下一次组会吹水。 …

大客户市场:阿里云、腾讯云、华为云“贴身肉搏”

配图来自Canva可画 近年来&#xff0c;随着中国逐渐进入数字化经济快车道&#xff0c;国内企业数字化、智能化升级已是刻不容缓。而为了帮助自身或其他企业实现数字化转型升级&#xff0c;阿里、腾讯、百度、京东、字节、网易、华为等众多国内知名企业早在多年以前&#xff0c…

【Git学习】Git如何Clone带有Submodule的仓库?

文章目录一、问题描述二、解决问题三、参考链接四、解决问题4.1 下载主模块4.2 查看主模块的配置4.2 子模块的添加4.3 查看子模块的配置4.4 查看子模块的检出状态4.5 检出submodule4.6 再次查看.git/config4.7 重新打开Android Studio运行代码一、问题描述 在GitHub上下载了一…

Android12 Launcher3 最近任务客制化

实现的最终效果: 目录 修改图标位置+添加应用名称 代码实现: 图标控件的边距调整:

微信小程序 button按钮怎么触发事件? bindtap语法怎么使用?

在前端网页中我们需要触发一个事件如果按钮点击后调用函数&#xff0c;文本、图片、链接被点击后调用一个函数一个事件&#xff0c;我们都知道用click&#xff0c;可是微信小程序中的click是不存在的&#xff0c;他怎么才能和网页中一样的使用click的呢&#xff1f; 1.bindtap语…

编程思想-0x00架构

产生架构的原因&#xff1f; 1、代码均摊 将不同的代码进行分块&#xff0c;然后简历联系&#xff0c;低耦合、高内聚&#xff1b; 原则上&#xff1a;合理的App架构应该是合理分配每个类、结构体、方法、变量的存在都应该遵循单一职责的原则 2、便于测试 测试确保代码质量&…

【编程基础之Python】3、创建Python虚拟环境

【编程基础之Python】3、创建Python虚拟环境创建Python虚拟环境为什么需要虚拟环境Windows上的Anaconda创建虚拟环境conda 命令conda env 命令创建虚拟环境切换虚拟环境验证虚拟环境Linux上的Anaconda创建虚拟环境创建虚拟环境切换虚拟环境验证虚拟环境总结创建Python虚拟环境 …

性能优化方向

性能怎么样就看io的应用&#xff0c;网络和数据库要好好设计&#xff0c;能一次查出来就一次。 对外接口尽量不要多创建对象&#xff0c; 少用bean复制 少用getbean(.class) 缓存不要频繁操作&#xff0c;最好异步 循环不要调用数据库&#xff0c;调用接口最好批量 Compon…

UG NX二次开发(C#)-UIStyler-创建长方体

文章目录 1、前言2、UG NX自动的创建长方体界面3、在块样式编辑器中创建UI界面4、创建一个工程5、在创建按钮中添加代码6、调用dll7、结论1、前言 UG NX二次开发中,UIStyler是一种非常高效的开发方式,UG NX已经为我们提供了比较完善的UIStyler开发模板,只要通过拖动的方式就…

GAN系列基础知识

原始值函数 原始GAN的值函数是 minGmaxDV(D,G)Ex∼pdata(x)[logD(x)]Ez∼pz(z)[log(1−D(G(z)))]min_Gmax_DV(D,G) E_{x \sim p_{data}(x)}[logD(x)]E_{z \sim p_{z}(z)} [log(1-D(G(z)))]minG​maxD​V(D,G)Ex∼pdata​(x)​[logD(x)]Ez∼pz​(z)​[log(1−D(G(z)))] 其中Ex…

尚医通(十二)SpringCloud相关概念介绍 | 搭建Nacos服务

目录一、什么是微服务1、微服务的由来2、为什么需要微服务3、微服务与单体架构区别4、微服务本质5、什么样的项目适合微服务6、微服务开发框架7、什么是Spring Cloud8、Spring Cloud和Spring Boot是什么关系9、Spring Cloud相关基础服务组件10、Spring Cloud的版本二、Nacos1、…

XXL-JOB 极简入门

文章目录1 概述2 特性3 架构设计3.1设计思想3.2 系统组成3.3架构图3.4 高可用3.4.1 调度中心的高可用3.4.2 执行器的高可用4 搭建调度中心4.1 克隆源码4.2 初始化 XXL-JOB 表结构修改配置文件4.4 修改日志配置文件4.5 IDEA 启动调度中心4.6 编译源码4.7 命令行启动调度中心4.8 …

D32 Vue2 + Vue3 K124-K143

D32.Vue F21.创建vue3项目&#xff08;K124-K129&#xff09; 该笔记是从vue2过渡到vue3的&#xff0c;所以不会特别详细的介绍某些vue2学过的&#xff0c;主要介绍vue3新增的 1.Vue3快速上手 A. Vue3简介 1&#xff09;2020年9月18日&#xff0c;Vue.js发布3.0版本&…

高性能(一)

思维导图 一、负载均衡 1.概念 将用户请求分摊到不同服务器上处理&#xff0c;以提高系统整体的并发处理能力及可靠性。 如图&#xff1a;我们用到负载均衡&#xff0c;实现访问商品服务的请求的分流。 负载均衡是一种常用且简单的提高系统并发和可靠性的手段&#xff0c;单…

MySQL入门篇-MySQL 二进制日志binlog介绍

MySQl binlog介绍 binlog的作用 逻辑日志,记录的是数据库内部的所有变动&#xff08;sql语句 行的改变&#xff09; server层日志&#xff0c;binlog不仅仅记录innodb的变动&#xff0c;也记录myisam存储引擎的变动。 innodb redo 是存储引擎层&#xff0c;和binlog不是一层&…