模板【类的基础】

#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;
}
View Code

 

posted @ 2021-07-19 14:13  bear_xin  阅读(13)  评论(0编辑  收藏  举报