#include<cstdio> #include<cmath> #include<algorithm> #include<set> #include<map> #include<cstring> #include<string> #include<vector> #include<queue> #include<iomanip> #include<iostream> #include<stack> using namespace std; //-------------------------------------------这样的线是分割线 //-------------------------------------------常用规定部分:都采用‘小写字母’+‘_’的方式 #define inf_ 0x3f3f3f3f #define reg_ register int #define ll long long #define for_reg(i, n) for(reg_ i = 1; i <= n; i++) //----------------------边访问 #define visit_edge int i = p[u]; ~i; i = e[i].next #define define_v int v = e[i].v #define define_v_avoid_f int v = e[i].v;if(v == fa) continue //----------------------线段树 #define mid_ int mid = (l+r)>>1//mid的定义 #define len_ (r-l+1)//像这样的式子千万要打括号,要不然就完了 #define l_id id<<1 #define r_id id<<1|1 #define l_son id<<1,l,mid #define r_son id<<1|1,mid+1,r #define include_(x,y,l,r) x<=l && r<=y const ll max_n = 3e4+10; const ll max_m = 6e4+10; //-----------------------------------------------变量声明部分:全局变量除第一个单词外其它单词首字母大写+结尾加一个g(global variable) class LeiMing { //private 、protected和public的出现次序可以是任意的。(也可以反复出现多次。) private://私有访问权限(也是默认访问权限)(私有成员被封装在一个类中,类的用户是看不见的) protected://保护成员(可以被类和该类的子类所看见) public://公有成员(类的用户可以调用的信息,是类对外的接口) //--------------数据成员(属性) /**数据成员的类型可以是C++基本数据类型,也可以是构造数据类型。**/ int num; //基本数据类型 //LeiMing *p; //构造数据类型 //LeiMing &p2;//正确(未完整定义类的引用) //LeiMing p3;//错误(未完整定义类,套娃错误) /**常数据成员同样也必须进行初始化,并且不能被更新。**/ /**老标准中以下语句错误,C++11中,是通过构造函数的初始化表进行初始化的**/ /**const数据成员的初始化只能在类构造函数的初始化表中进行,不能在构造函数中对他赋值。(ps:构造函数初始化表也可以对普通数据成员赋值)**/ /* private: const int a; //常数据成员 const int& r; //常引用数据成员 public: A(int i):a(i),r(a) //常数据成员只能通过初始化列表来获得初值 { cout<<"constructor!"<<endl; }; */ //静态数据成员 /**静态数据成员的定义分为两个必不可少的部分:类内声明、类外初始化。(静态数据成员的初始化与它的访 问控制权限无关)**/ /**静态数据成员脱离具体对象而独立存在,其存储空间是独立分配的,不是任何对象存储空间的一部分**/ /**静态数据成员初始化时前面不加static关键字,以免与一般静态变量或对象混淆。**/ //在类内,声明静态数据成员的格式为 :static 数据类型 静态数据成员名; //在类外初始化的形式为:数据类型 类名::静态数据成员名=初始值; //静态的常量成员的声明: static const 类型 数据成员名 = 常量表达式; //const int A::b=3; //静态常数据成员在类外说明和初始化 //可以通过作用域操作符从类直接调用。如: SavingAccount::rate //但从每个对象的角度来看,它似乎又是对象的一部分,因此又可以从对象引用它。如有个SavingAccount类的对象obj,则可以用:obj.rate const int siz = 100; int const a = 100; //int b[siz];//错误,未知的SIZE。即使在C++11中,SIZE也是在程序运行时通过构造函数赋值,所以编译时SIZE并没有值 //--------------函数成员(方法) //成员函数的定义、声明格式与非成员函数(全局函数)的格式相同。 //成员函数可以放在类中定义,也可以放在类外。 //放在类中定义的成员函数为内联(inline)函数。 /**C++可以在类外定义函数体,但必须同时在类内声明成员函数的原型。(这样做的好处是使我们对类的成员函数的功能一目了然)**/ void f(int a);//在类中声明函数原型的方法与一般函数原型的声明一样 //---------------构造函数 /**构造函数是与类名相同的,在建立对象时自动调用的函数。**/ /**一个类可以有多个构造函数,即重载 ,可根据其参数个数的不同或参数类型的不同来区分它们。**/ /**没有返回值,也不能用void来修饰**/ /**构造函数不能被直接调用,必须在创建对象时才会由编译器自动调用**/ /**当定义一个类定义的时候,如果用户没有定义构造函数,编译器会提供一个默认的构造函数,即LeiMing()的空构造函数(但如果用户为类定义了任何一个构造函数,C++就不会生成任何默认的构造函数)**/ /**构造函数一般情况下被声明定义为公有函数。(???也许是因为继承的关系)**/ /**对象数组的初始化格式如下:(好像也可以不加第二、第三、第四个“类名”) 类名 数组名[n]={ 类名(数据成员1初值,数据成员2初值,…), 类名(数据成员1初值,数据成员2初值,…), 类名(数据成员1初值,数据成员2初值,…)};**/ /**建议:如果为一个类定义了带参数的构造函数,那么,请再定义一个无参数的构造函数。**/ //----------------拷贝构造函数 /**如果用户没有定义拷贝构造函数,系统会定义一个缺省的拷贝构造函数。该函数将已存在的对象的数据成员的值一模一样地复制给新对象。**/ /**那么我们为何不直接使用系统默认的拷贝构造函数,何必又自己定义一个拷贝构造函数呢?原因在于默认的拷贝构造函数实现的只能是浅拷贝 即直接将原对象的数据成员值依次拷贝给新对象中对应的数据成员,并没有为新对象另外分配内存资源。这样,如果对象的数据成员是指 针,两个指针对象实际上指向的是同一块内存空间。 **/ /**当类的数据成员中有指针类型时,我们就必须定义一个特定的拷贝构造函数,该拷贝构造函数不仅可以实现原对象和新对象之间数据成员的拷 贝,而且可以为新的对象分配单独的内存资源,这就是深拷贝构造函数。**/ /**用一个已存在的对象去初始化一个新建立的对象。**/ /**拷贝构造函数原型:类名(const 类名& 对象名){ … };**/ /**以下三种情况相当于用一个已存在的对象去初始化新建立的对象, 此时, 调用拷贝构造函数: ①对象定义时:用类的一个对象去初始化该类的另一个对象时。 ② 函数参数传递时:如果函数的形参是类的对象,调用函数时,将对象作为函数实参传递给函数的形参时。 ③ 函数返回值时:如果函数的返回值是类的对象,函数执行完成,将返回值返回时 **/ /**以下情况不调用拷贝构造函数,而执行“等于号 ”操作:Clock myClock2=myClock1 ;**/ //----------------析构函数 /**析构函数(destructor)也译作拆构函数, 是在对象消失之前的瞬间自动调用的函数**/ /**如果用户没有定义析构函数,系统将自动生成一个不做任何事的默认析构函数**/ //----------------常成员函数 /**常成员函数不能更新对象的数据成员,也不能调用该类中没有用const修饰的成员函数。**/ /**常对象只能调用它的常成员函数,而不能调用其他成员函数。**/ /**const关键字可以用于参与重载函数的区分**/ int get() const { return this->num; } //静态函数 /**由于静态成员函数不需要借助任何对象就可以被调用。因此,静态成员函数无法处理类中的非静态成员变量,也不允许使用this指针。**/ /**静态成员函数的声明只需要在类定义中的函数原型(声明)前加上保留词static。(在类外定义时,不用static)**/ }; //-------------------------------------------------函数声明部分:函数的单词首字母大写,常用局部变量简化 //--------------------------------------------------main函数部分 int main() { //freopen("in.txt","r", stdin); //freopen("out.txt","w", stdout); ios::sync_with_stdio(false); LeiMing A;//创建类的对象(由虚的概念到分配了空间的实体) A.num = 1;//调用用.号 A.f(1); //类的指针 LeiMing *B; B = &A; B->num = 1; B->f(1); //引用 LeiMing &C = A; A.num = 1; //动态对象 B = new LeiMing; delete B; //动态对象数组 B = new LeiMing[10]; delete [] B; return 0; //常对象 /**常对象只能调用它的常成员函数,而不能调用其他成员函数。**/ const LeiMing C1(9,9,9); //定义常对象C1 Leiming const C2(10,10,10); //定义常对象C2 } //---------------------------------------------------函数定义部分 //::是类的作用域分辨符,用在此处,放在类名后成员函数前,表明后面的成员函数属于前面的那个类。 void LeiMing::f(int a)//类外定义函数体 { /**在成员函数里面是可以使用该类定义对象的,因为调用成员函数时类已经定义完毕,当然可以使用已定义完整的类类型的变量**/ /**一个类的成员函数中,有时希望引用调用它的对象,对此,C++采用隐含的this指针来实现。(????????)**/ this->num = a;//等价于(*this).num = a; //function return; }