类(class)

        类是 C++中一个非常重要的元素,可以说是 C++的灵魂所在了,我们都知道 C++说一种面向对象的编程语言,那么面向对象是一种什么概念呢?在 C++程序设计中,所有一切东西都可以称之为对象,任何对象都应该具有属性和行为。例如一台电脑,属性有电脑的相关配置,功能是可以玩游戏,可以打字等等。而类就是描述一个对象的一种概念,例如我们创建一个人类,那么人这个类其实就是一种概念,并不是实际的某个人,而是人的一些特征集合,具体到某个人,例如张三,那么张三就是一个对象,他有名字有身高体重,行为可以跑步,可以吃饭等等。所以我们一定要理解类其实就是保存一类对象的特征的集合。
        在 c 语言中,我们来表示一个东西的特征的时候,我们使用的是结构体来表示,例如:表示一个人
struct person
{char name[16]; //名字float height; //身高float height; //体重char cell[32]; //手机号
};
        定义号一个人的属性之后,如果想对这个人有所操作的话,就要去定义函数,然后去在主函数中去实现一些函数的过程逻辑,所以说 c 语言是一种面对过程编程的语言,而在 C++中,对结
构体进行了一个升级,可以在里面去定义函数来表示这类对象的一些行为,同时可在里面设置一些权限实现封装,使其内部元素对外隐藏,只提供一些对外接口和外部对接,这就是 C++的一个封装性。
class person
{private:char name[16]; //名字float height; //身高float weight; //体重char cell[32]; //手机号public:int running(char *WayName,int time); //跑步行为int eat(char *ObjectName,int l); //存放行为
};

class 和 struct 在 C++中的区别

在 C++中同样也是可以使用 struct 来表示类的,它们所具有的功能完全一致,只有以下几点不同:
1.默认继承权限
        使用 struct 默认继承权限是公有的(public),而 class 默认继承权限是私有的(private)
2.默认访问权限
        struct 的默认访问权限是公有的,而 class 的默认访问权限是私有的。

类的访问修饰符

访问修饰符描述了类中成员的访问权限(哪些成员是可以直接访问的,哪些不能访问)
[public]:
        public 修饰的成员,称为公有成员,在任何地方都可以直接访问
[private]:
        private 修饰的成员,称为私有成员,只有本类的成员函数和友元函数才可以访问
[protected]:
        protected 修饰的成员,称为受保护的成员,只有本类的成员函数和友元函数和它的派生类才可以访问
        一般来说,我们一般将类的属性信息设置为私有的,外界不可访问,这样就保护了我们的对象不被轻易改变,而把一些行为接口设置为公有的供外部去对我们的这个对象进行操作。

构造函数和析构函数

        在类中,默认会有一个构造函数和一个析构函数,在定义对象的时候,程序会自动去执行构造函数对对象进行初始化,释放对象时会自动调用析构函数去对对象进行释放,构造函数的名字和类名一样,没有返回值,析构函数名字则是在类名的前面加上~号,无参数也没有返回值,程序员也可以重写构造函数和析构函数,为对象中的属性值进行初始化和释放,例如:
#include <iostream>
#include<string.h>
using namespace std;
class person
{private:char name[16]; //名字float height; //身高float weight; //体重char cell[32]; //手机号public:person();person(const char *ne,float h,float w,const char *ce);~person(){cout << name <<":执行了析构" << endl;}void run(){cout << "名字:"<< name << endl;cout << "身高:"<< height << endl;cout << "体重:"<< weight << endl;cout << "手机号:"<< cell << endl;}int running(char *WayName,int time); //跑步行为int eat(char *ObjectName,int l); //存放行为
};
person::person()
{strcpy(name,"zhangsan");height = 168.4;weight = 64.2;strcpy(cell,"17873432557");
}
person::person(const char *ne,float h,float w,const char *ce)
{strcpy(name,ne);height = h;weight = w;strcpy(cell,ce);
}
int main()
{person a; //创建一个对象,执行的是没有参数的构造函数person b{"jiuyue",178.7,76.6,"110"}; //创建一个对象执行有参数的构造函数a.run();b.run();return 0;
}

        构造函数可以传递参数对类中成员进行赋值, 也可以不传递,实例化对象时,程序会利用函数重载自动匹配调用哪个构造函数,但是析构函数不同了,析构函数是不可以带参数的。
注意: 在实例化对象的时候,如果想要程序去匹配没有参数的构造函数时,一定不要这样写
person a ();
系统会认为你这是一个函数声明,不会认为你这是一个对象的实例化,所以你只能是以下写法:
person a ;
//
person a {};

构造函数初始化列表

构造函数的初始化列表是对构造函数的一种升级,以下情况必须用初始化列表:
        1.成员对象没有默认构造函数
        2.成员变量是常量
        3.成员变量是引用
        4.初始化基类的成员
        构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式。例如:
class CExample
{public:int a;float b;
//构造函数初始化列表CExample(): a(0),b(8.8){}
//构造函数内部赋值CExample(){a=0;b=8.8;}
};
        上面的例子中两个构造函数的结果是一样的。上面的构造函数(使用初始化列表的构造函数)显式的初始化类的成员;而没使用初始化列表的构造函数是对类的成员赋值,并没有进行显式的初始化。

我们来看第一种情况为什么要使用构造函数初始化列表:(成员对象没有默认构造函数)

#include <iostream>
#include<string.h>
using namespace std;
class A
{private:int a;char b;public:A(int x,char y){a = x;b = y;cout << "a 的构造" << endl;}
};
class B
{private:A a;int c;public:B(int z,char n,int x):a(z,n){ c = x;}
};
int main(int argc, char const *argv[])
{B b(1,'2',3);return 0;
}
        例如上面程序,如果 B 类中有成员变量 A 类,B 类想要在构造函数中去对 a 进行初始化赋 值,如果不使用构造函数初始化列表的方式,就无法做到在构造函数内部去调用 a 的构造函数去对 a 进行初始化。
再来看第二种情况和第三种情况(成员变量是常量或引用)
#include <iostream>
#include<string.h>
using namespace std;
class A
{private:int a;const int b;char& c;public:A(int x,char y):b(x),c(y){a = 3;//b = 4; //const 常量只能在声明时初始化,之后不能改变//c = ? //引用只能在声明的时候进行初始化}
};
int main(int argc, char const *argv[])
{char i = '1';A(4,i);return 0;
}
        如上程序,在类 A 中有常量成员和引用成员,因为这两个成员只能在声明时进行赋值初始 化,其他时候都不能对其值进行改变,所以必须使用构造函数初始化列表那么最后一种就容易理解了(初始化基类的成员),因为子类无法访问基类的私有成员,所以必然不可能在构造函数体中对基类成员进行初始化,只能使用初始化成员列表对基类初始化,例如下面程序。
#include <iostream>
#include<string.h>
using namespace std;
class A
{private:int a;const int b;char& c;public:A(int x,char y):b(x),c(y){a = 3;//b = 4; //const 常量只能在声明时初始化,之后不能改变//c = ? //引用只能在声明的时候进行初始化}
};
class B:public A
{private:int x;public:B(int a1,char b1):A(a1,b1){x = 2;}
};
int main(int argc, char const *argv[])
{char i = '1';B(4,i);return 0;
}

结论

其实通过上面的学习我们大概了解了构造函数初始化列表的作用了,简单来说就是:
int a = 3;
const char c = '1';
A b(2,5);
上面这种初始化方式为显性赋值,因为它们是声明时就初始化了。
int a;
const char c;
A b;
a = 3;
c = '1' //error
b(3,5); //error
        而上面这种赋值就属于隐性赋值,可以看到,很多东西是不允许隐性赋值的,例如常量, 引用,类。
而对构造函数进行初始化成员列表进行初始化其实就是对类的成员进行显性赋值

临时对象

        临时对象是指在函数传参或者函数返回的时候,临时创建的,没有名字的对象,用完以后会立即销毁这种对象。

例如:

#include <iostream>
#include<string.h>
using namespace std;
class A
{private:int a;int b;public:A(int x,int y):a(x),b(y){cout << "构造" <<endl;}~A(){cout << "析构" <<endl;}
A fun()
{return A(a,b);
}
};
int main(int argc, char const *argv[])
{A i = A(1,2);A j = i.fun();return 0;
}
直接调用构造函数将产生一个临时对象。
临时对象的声明周期只有一条语句的时间。
临时对象的作用域只在一条语句中。
临时对象是 C++中值得警惕的灰色地带。

类的只读成员函数

        在 c++中我们知道 const 可以用来指定变量为只读变量,那么在 C++中,我们还可以使用 const 来修饰类中的成员函数,例如:
class A
{private:int a;int b;public:A(int x,int y):a(x),b(y){}int fun() const{//...}
};
        如上程序,类中的 fun()函数被 const 修饰后,那么在 fun()函数中将不能对类的成员变量进行改变。这就是 const 修饰类中成员函数的作用。

拷贝构造函数

        拷贝构造函数是一种特殊的构造函数,它在创建对象时, 是使用同一类中之前创建的对象 来初始化新创建的对象 。拷贝构造函数通常用于:
        •通过使用另一个同类型的对象来初始化新创建的对象。
        •复制对象把它作为参数传递给函数。
        •复制对象,并从函数返回这个对象。
函数形式:
类名 (const 类名 &)
注意:
        在类中有一个默认的赋值操作,容易和拷贝构造搞混淆,赋值操作是当= 两边都是已经初始化好的对象进行赋值时才会调用赋值函数,而当用一个已经初始化好的对象去初始化另一个对象时,那么另一个对象就调用的是拷贝构造函数。
        如果在类中没有定义拷贝构造函数,编译器会自行定义一个。如果类带有指针变量,并有动态内存分配,则它必须有一个拷贝构造函数。拷贝构造函数的最常见形式如下:
class A
{private:int a;int b;public:A(int x,int y):a(x),b(y){} //构造函数初始化列表A(const A &obj) //拷贝构造函数{// 构造函数的主体}
};
当对对象进行拷贝赋值时就会调用拷贝构造函数进行初始化赋值,如
int main(int argc, char const *argv[])
{A i(1,2);A j = i; //调用了拷贝构造A k(i); //调用了拷贝构造return 0;
}

省略复制

        复制省略是自 C++11 标准起提出的一项编译优化技术,通过省略复制及移动构造函数的调用,实现零复制的值传递语义。省略复制一般默认存在,可以通过在编译时添加-fno-elide
constructors 选项来关闭省略复制 。在以下两种情况中会出现省略复制。
1. 在变量初始化中,当初始化表达式 ( 右值 ) 与变量类型为同一类型的纯右值 ( 临时量 ) 时,
例如:
#include <iostream>
#include<string.h>
using namespace std;
class A
{private:char buf[16];public:A(const char *str){strcpy(buf,str);cout << "构造函数" << endl;}A(const A& a){strcpy(this->buf,a.buf);cout << "拷贝构造" << endl;}
};
int main()
{A ob = "nihao";return 0;
}

上面是进行了省略构造后的结果,那关闭省略构造呢?

        可以看到,不进行省略复制就会执行拷贝构造函数,省略复制相当于把 A ob = “nihao” 变成了 A ob( nihao ); 直接将对象构造到它们本来要拷贝的存储空间 , 而不进行省略复制, A ob = “nihao”相当于 A ob = A(“nihao”)
2. 第二种情况是在 return 语句中,操作的对象是与函数返回类型为同一类型的纯右值 ( 临时量) 时,例如:
#include <iostream>
#include<string.h>
using namespace std;
class A
{private:char buf[16];public:A(const char *str){strcpy(buf,str);cout << "构造函数" << endl;}A(const A& a){strcpy(this->buf,a.buf);cout << "拷贝构造" << endl;}
};
A fnn()
{return A("nihao");
}
//或
A fuu()
{A a("nihao");return a;
}
int main()
{A ob = fuu();return 0;
}

上图是进行了省略复制的结果

        上图是不进行省略复制的结果,可以看到,原本的 A ob = fuu(); 在不进行省略复制的情况 下,编译器会被解释为 A ob = A(fuu());

this 指针

        在 C++ 中,每一个对象都能通过 this 指针来访问自己的地址。 this 指针是所有成员函数的隐含参数( 也就是所有成员函数都默认有一个隐藏的指针参数保存着对象的地址 ) 。因此,在成员函数内部,它可以用来指向调用对象。
        友元函数没有 this 指针,因为友元不是类的成员。只有成员函数才有 this 指针。静态成员函数也没有 this 指针,因为静态成员函数不属于某个对象,只属于类本身。
class A
{private:int a;int b;public:A(int x,int y):a(x),b(y){} //构造函数初始化列表void fun(){this->a = 4; //this 就是该对象的地址(*this).b = 5; //*this 就相当于对象本身}
};
        如上,我们可以在成员函数中利用 this 来操作成员变量,至于这个 this 是谁的地址,那就要看是哪个对象了,例如:a.fun();那么 this 就指向 a 这个对象,b.fun();那么 this 就指向 b 这个对象,this 其实用处很多,如下面程序:
class A
{private:int a;int b;public:A(int x,int y):a(x),b(y){} //构造函数初始化列表void fun(int a,int b){//a = a; //erreor ,系统会以为是形参 a 赋值给形参 a,并不会改变成员变量的值//b = b; //同上理this->a = a;this->b = b;}
};
        当参数的名字和成员的名字相同时,那么就必须使用 this 去做区分了。
        总之,我们理解 this 是成员函数中隐藏的一个指向对象地址的一个指针就可以了,就相当于原本类中的函数应该都是下面这样的:
void sun ( A * this );
void fun ( int a , int b , A * this );
        每个函数中都必须有一个类指针 this,当调用它时,就会默认传入调用者对象的地址,如 下:
A a ( 1 , 2 );
a . sun (& a );
a . fun ( 1 , 2 ,& a );
但是,你可以理解为系统将这些东西都隐藏了。

类的静态成员函数

        静态成员函数是使用 static 修饰的成员函数,只能被定义一次,而且要被同类的所有对象所共享,它是类的一种行为,与对象无关。
class person
{
public:static void func(); //只需要在类内进行声明
};
它有如下特点: 1. 静态成员函数不可以直接访问类中非静态数据成员以及非静态成员函数,只能通过对象名(由参数传入)来访问,即在类的静态成员函数(类的静态方法)内部,不能直接访问 this 指针和对象的数据成员,在类的静态成员函数(类的静态方法)内部,只能访问类的静态数据
成员!
2. 静态成员函数在类外定义时,无需加 static 修饰,否则出错;

3. 在类外,可以通过对象名以及类名来调用类的静态成员函数和变量
4. 对象和类可以直接访问静态成员函数,静态成员之间在类中可以相互访问,包括静态成员函数访问静态数据成员和访问静态成员函数;
5. 在类外,可以通过对象名以及类名来调用类的静态成员函数,静态成员函数不能访问非静态成员函数和非静态数据成员;
6. 声明静态成员函数时,不可同时声明为 virtual const volatile 函数
7. 静态函数可以使用作用域标识符直接访问,无需创建任何对象就可以访问
int main(int argc, char const *argv[])
{A::fun();return 0;
}
8. 类的静态成员变量必须在类外进行初始化才能被使用,否则报错,例如:
class A
{private:int a;int b;static int c;public:static void fun();
};
int A::c = 0; //静态成员变量初始化
可以使用对象操作静态成员变量,也可以使用类本身,前提是静态成员变量是公有的,如下程序:
#include <iostream>
#include<string.h>
using namespace std;
class A
{private:int a;int b;public:static int c;static void fun(){cout << c << endl;}
};
int A::c = 0;
int main(int argc, char const *argv[])
{A a;a.c = 0;A::c = 5;a.fun();return 0;
}

友元函数和友元类(friend)

        按 c++的封装性来说,最主要的目的就是确保数据的安全,实现信息的隐藏,从原则上来 说,类的私有成员和保护成员,在类的外部是不能直接访问的,但是,有一个例外,这个就是友元(friend),友元就是在类的声明中,用关键字 friend 修饰的函数或者类,友元授予一个函数或者一个类特权,允许他们能直接访问本类的隐藏信息.

友元函数

        友元函数不是类的成员函数,但是仍可以访问该类的私有成员。友元函数可以是一个外部函数,也可以是另一个类的成员函数。
        友元函数可以访问类中的私有成员和其他数据,但是访问不可直接使用数据成员,需要通 过对对象进行引用,所以友元函数必须有一个参数用来传递对象的地址或引用
当友元函数是全局类外函数时在类中声明的格式:
friend 返回值类型 函数名(参数列表);
如下是当类外函数做友元的示例:
#include <iostream>
#include<string.h>
using namespace std;
class A; //对 A 进行超前声明,不然 sun 参数找不到
int sun(int a,int b,A& c);
class A
{private:int x;int y;public:A(int a,int b):x(a),y(b){}~A(){}friend int sun(int a,int b,A& c);
};
int sun(int a,int b, A& c)
{c.x = a;c.y = b;return c.x+c.y;
}
int main(int argc, char const *argv[])
{A a(2,4);sun(1,2,a);return 0;
}
        特别要注意的是,在对函数声明时,一定要对类进行超前声明,因为在对函数声明中有个参数是这个类,不进行超前声明函数会找不到这个类的定义。还有在友元函数在调用上同一般函数一样,不必通过对对象进行引用。
        当友元函数是另外一个类中的成员函数时在类中声明的格式:
friend 返回值类型 类名::函数名(参数列表);
如下是当其他类的成员函数做友元的示例:
#include <iostream>
#include<string.h>
using namespace std;
class A; //对 A 进行超前声明,不然 sun 参数找不到
class B
{private:int i; char j;public:B(int a,char c){i = a;j = c;}~B(){}int fun(A *rm);
};
class A
{private:int x;int y;public:A(int a,int b):x(a),y(b){}~A(){}friend int B::fun(A* rm); //友元
};
int B::fun(A *rm)
{i = rm->x + rm->y;j = 'a';return i;
}
int main(int argc, char const *argv[])
{A a(2,4);B b(2,'A');b.fun(&a);return 0;
}

友元类

        可以将一个类定义为另一个类的友元,这样,被定义为友元的类中的函数就可以访问另一个类中的所有内容了, 这样是不安全的。最好的方法就是哪个需要访问,就设置为友元函数即可。
当其他类是友元类时在类中声明的格式:
friend 类名;
如下是当其他类做友元的示例:
#include <iostream>
#include<string.h>
using namespace std;
class A; //对 A 进行超前声明,不然 sun 参数找不到
class B
{private:int i; char j;public:B(int a,char c){i = a;j = c;}~B(){}int fun(A &a);
};
class A
{private:int x;int y;friend B;public:A(int a,int b):x(a),y(b){}~A(){}
};
int B::fun(A &a)
{i = a.x + a.y;return i;
}
int main(int argc, char const *argv[])
{A a(2,4);B b(2,'A');b.fun(a);return 0;
}

友元注意事项

        1.友元关系是单向的,如 类 A 声明它有一个朋友 B,即 B 是 A 的朋友,反过来,A 不一定是 B 的朋友
        2. 友元关系是不可传递的,如 A 是 B 的朋友,B 是 C 的朋友,A 不一定是 C 的朋友
        3. 一个函数可以是多个类友元函数。

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

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

相关文章

C++基础——类与对象

1 概述 C是面向对象的语言&#xff0c;面向对象语言三大特性&#xff1a;封装、继承、多态。 C将万事万物抽象为对象&#xff0c;对象上有其属性和行为。 2 封装 2.1 封装的意义 封装是面向对象的三大特性之一&#xff0c;封装将属性和行为作为一个整体&#xff0c;对属性和…

灵活调整宣传策略,媒体发稿和新闻发布的优势所在

企业在当今信息爆炸的时代&#xff0c;要想在市场竞争中脱颖而出&#xff0c;提高公信力是至关重要的。而媒体发稿和新闻发布是提升企业公信力的重要手段之一。下面将从门户网站的权威展示、搜索引擎排名的提升、内容的持续稳定有效性、内容的可改性以及协助增加网站流量等方面…

浅谈自动化测试框架开发

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;欢迎加入我们一起学习&#xff01;&#x1f4e2;资源分享&#xff1a;耗时200小时精选的「软件测试」资…

Linux中for循环

for do done 复习知识点&#xff1a;cut命令&#xff0c;id命令&#xff0c;finger命令&#xff0c;for循环 程序如上&#xff0c;-d 接分隔符&#xff0c;-f后的数字表示分隔后的列 从结果可以看出&#xff0c;系统上没有finger这个命令&#xff0c;后面会学到yum安装命令&a…

Python---字符串的修改方法---replace()替换

修改字符串&#xff0c;指的就是通过函数&#xff08;方法&#xff09;的形式修改字符串中的数据。 编号函数作用1replace()返回替换后的字符串2split()返回切割后的列表序列3capitalize()首字母大写4title()所有单词首字母大写5upper()与lower()返回全部大写或小写的字符串6l…

[动态规划] (九) 路径问题:LeetCode 64.最小路径和

[动态规划] (九) 路径问题&#xff1a;LeetCode 64.最小路径和 文章目录 [动态规划] (九) 路径问题&#xff1a;LeetCode 64.最小路径和题目解析解题思路状态表示状态转移方程初始化和填表顺序返回值 代码实现总结 64. 最小路径和 题目解析 (1) 从左上角到右下角 (2) 只能向右…

ardupilot开发 --- gdb 篇

环境 win11 vscode 1.81.0 wsl2 ardupilot 利用gdb工具在vsCode中实现 Ardupilot SITL的断点调试 优点&#xff1a;可在vsCode中实现断点调试。 参考文献&#xff1a;https://ardupilot.org/dev/docs/debugging-with-gdb-using-vscode.html 安装gdb工具 打开wsl&#xff0…

剑指JUC原理-13.线程池

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码&#x1f525;如果感觉博主的文章还不错的话&#xff0c;请&#x1f44d;三连支持&…

从NetSuite Payment Link杂谈财务自动化、数字化转型

最近在进行信息化的理论学习&#xff0c;让我有机会跳开软件功能&#xff0c;用更加宏大的视野&#xff0c;来审视我们在哪里&#xff0c;我们要到哪去。 在过去20多年&#xff0c;我们的财务软件经历了电算化、网络化、目前处于自动化、智能化阶段。从NetSuite这几年的功能发…

【Effective Modern C++】条款2:理解auto类型推导

条款2&#xff1a;理解auto类型推导 条款1中&#xff0c;模板类型推导的函数模板形如&#xff1a; template<typename T> void f(ParamType param);当变量采用auto声明时&#xff0c;auto扮演了模板中的T这个角色&#xff0c;而变量的类型扮演的是ParamType的角色。 条…

Django实战项目-学习任务系统-查询列表分页显示

接着上期代码框架&#xff0c;6个主要功能基本实现&#xff0c;剩下的就是细节点的完善优化了。 接着优化查询列表分页显示功能&#xff0c;有很多菜单功能都有查询列表显示页面情况&#xff0c;如果数据量多&#xff0c;不分页显示的话&#xff0c;页面展示效果就不太好。 本…

Spring AOP 简介

一、Spring AOP AOP 是一种思想&#xff0c;而 Spring AOP 是一个框架&#xff0c;提供了一种对 AOP 思想的实现。 1、什么是 AOP&#xff1f; AOP&#xff08;Aspect Oriented Programming&#xff09;&#xff1a;是一种编程思想&#xff0c;表示面向切面编程。指的是对某…

python栈_简单算术表达式_加减乘除

# 从左到右遍历中缀表达式中的每个数字和符号&#xff0c;若是数字就输出&#xff0c;即成为后缀表达式的一部分&#xff1b;若是符号则要分为两种情况&#xff1a; # (1)是括号时&#xff0c;如果是左括号&#xff0c;直接将左括号入栈&#xff0c;如果是右括号则栈顶元素依次…

插件_日期_lunar-calendar公历农历转换

现在存在某需求&#xff0c;需要将公历、农历日期进行相互转换&#xff0c;在此借助lunar-calendar插件完成。 下载 [1] 通过npm安装 npm install lunar-calendar[2]通过文件方式引入 <script type"text/javascript" src"lib/LunarCalendar.min.js">…

React 项目结构小结

React 项目结构小结 简单的记录一下目前 React 项目用的依赖和实现 摸索了大半年了大概构建一套用起来还算轻松的体系……&#xff1f;基本上应该是说可以应对大部分的项目了 使用的依赖 目前项目还在 refactoring 的阶段&#xff0c;所以乱得很&#xff0c;这里是新建一个…

有什么好用的CRM客户管理系统?推荐这5大高口碑的CRM系统!

有什么好用的CRM客户管理系统&#xff1f;推荐这5大高口碑的CRM系统&#xff01; 好用的CRM客户管理系统&#xff1a; ①需要进行精细化管理 ②需要专业的管理工具 ③最好能够做到和erp系统和oa系统的集成 授人以鱼不如授人以渔&#xff0c;在给题主推荐crm系统之前&#…

高数笔记06:无穷级数

图源&#xff1a;文心一言 时间比较紧张&#xff0c;仅导图~~&#x1f95d;&#x1f95d; 第1版&#xff1a;查资料、画导图~&#x1f9e9;&#x1f9e9; 参考资料&#xff1a;《高等数学 基础篇》武忠祥 &#x1f433;目录 &#x1f433;常数项级数 &#x1f40b;概要 &…

C++基础——对于C语言缺点的补充(2)

上篇文章中说到&#xff0c;为了解决C语言会出现人为定义的函数和库函数出现重定义的错误&#xff0c;C引入了一个新的概念&#xff0c;即命名空间&#xff0c;通过认为定义命名空间&#xff0c;来解决上述问题。 在本篇文章中&#xff0c;将继续介绍C相对于C语言不足来进行的补…

Harbor企业级Registry基础镜像仓库的详细安装使用教程(保姆级)

Harbor Docker 官方提供的私有仓库 registry&#xff0c;用起来虽然简单 &#xff0c;但在管理的功能上存在不足。 Harbor是vmware一个用于存储和分发Docker镜像的企业级Registry服务器&#xff0c;harbor使用的是官方的docker registry(v2命名是distribution)服务去完成。 ha…

数据结构之堆的实现(图解➕源代码)

一、堆的定义 首先明确堆是一种特殊的完全二叉树&#xff0c;分为大根堆和小根堆&#xff0c;接下来我们就分别介绍一下这两种不同的堆。 1.1 大根堆&#xff08;简称&#xff1a;大堆&#xff09; 在大堆里面&#xff1a;父节点的值 ≥ 孩子节点的值 我们的兄弟节点没有限制&…