zoukankan      html  css  js  c++  java
  • 静态友元常量成员

    静态 友元 常量 成员

    学习类中的一些特殊的成员,掌握他们的使用以及特点

    一、静态成员

    1、知识点

    void fun()
    {
        static int a=10;//只会创建一次,第二次调用的时候就不执行了,但是a已经变成11了
        a++;
        cout<<a<<endl;
    }
    int main()
    {
        fun();//11
        fun();//12
    }
    

    int a;==>声明

    int a=10;==>初始化:在定义的时候赋值

    赋值:在声明完之后,用“="给标识符赋值

    1.静态成员指的是在c++类中声明成员时,可以加上static关键字,这样声明的成员叫静态成员,静态成员分为静态数据成员和静态函数成员两种

    2、静态数据成员定义

    class node
    {
     public:
        static int id;//静态数据成员定义
    }
    int node::id=10;//静态数据成员必须在类外初始化
    

    3、静态数据成员的特点

    1.类中静态数据成员,所有对象都共享该数据,只有一份内存在内存中

    2.类中的静态数据成员,必须要在类外初始化,因为他不属于对象,属于类,对象存在或者不存在,这个静态数据成员都是存在的,而且静态数据成员的声明周期是:程序开始就存在(主函数运行之前),直到程序结束才被释放(无论是什么属性)

    3.类中的静态数据成员,可以在类中被重新赋值(必须要在类外初始化之后才能再在类中赋值),可以被普通函数访问,如果该成员是公有属性,那么就还可以在类外被对象自己访问,或者通过类名访问

    访问方式:类名::静态数据

    class A
    {
        public:
        A()
        {
            cout<<"A构造"<<endl;
        }
    }
    class person
    {
        static A* ss
    	static int num;
    public:
    	static int sum;//静态数据成员
    	void setnum(int num)//给私有属性提供的公有属性接口
    	{
    		this->num = num;
    	}
    	int getnum()
    	{
    		return num;
    	}
    	person()
    	{
    		sum = 10;//这是赋值操作
    		num = 20;
    	}
    };
    int person::sum = 0;//类外初始化操作
    int person::num = 0;
    A* person::ss=new A;
    //静态数据成员不能在类中初始化,必须要在类外初始化
    //类型 类名::静态成员=值
    
    int main()
    {
    	person p;//实例化对象
    	cout << p.sum << endl;
    	cout << p.getnum() << endl;
    	person p1;
    	p1.setnum(99);
    	cout << p.getnum() << endl;
    	cout << p1.getnum() << endl;
        //类中的静态数据成员,所有的对象都共用这一个成员,这个静态数据成员只有一份内存在内存中
    	getchar();
    	getchar();
    	return 0;
    }
    
    

    node::id;

    node n; n.id;

    4、静态函数成员定义

    class node
    {
     public:
        static void fun(){}//类中定义
        static void fun1();//类中声明
    }
    void node::fun1(){}//在类外定义
    

    5、静态函数成员的特点

    class person
    {
        static int sum;
        public:
        static int getsum()
        {
            return sum;
        }
    }
    int person::sum=10;
    int main()
    {
        cout<<person::getsum()<<endl;//10
    }
    

    1.类中的静态函数成员,这个函数同样也不属于对象,而是属于类的,所以这个函数中不能操作类中的普通数据成员和普通函数成员。因为这些普通成员时必须要有对象的时候才会被建立,而静态函数不用对象也能调用

    2.访问和静态数据成员一样

    3.在这个静态函数成员中,不能访问这个类的普通成员,因为那些普通成员时需要有对象才会创建的,但是静态函数成员没有对象也能使用。可以在这个静态函数中使用局部变量,形参,静态数据成员

    4.一般静态函数成员是用来操作静态数据成员的,在这个函数中,我们可以操作的数据是不属于对象的数据

    6、单例模式

    1.现在对于设计模式,没有太过详细去讲,把这个单例模式理解为一个套路,在特定的情况下使用

    2.单例模式是一种常用的软件设计模式。通过单例模式可以保证系统中,应用该模式的类只有一个实例对象

    单例模式的类中提供私有下的构造函数(默认,拷贝构造就够了)

    包含一个本身这个类的私有的静态对象(指针或实例化的,几乎写的都是指针的)

    提供一个静态的公有函数去创建或获取这个私有对象

    在单例模式中的类中,把构造函数写在私有属性下面(默认,拷贝)

    包含一个自身这个类类型的指针(静态)

    #include<iostream>
    using namespace std;
    
    class Person
    {
    	Person()
    	{
    		cout << "对象创建" << endl;
    	}
    	Person(const Person&p){}//拷贝构造
    	//这两个函数在私有属性下面,不能创建对象访问
    	static Person* person;//通过创建一个静态的指针对象,来访问
    public:
    	static Person* getperson()
    	{
    		return person;
    	}
    	void speak()
    	{
    		cout << "我是单例模式" << endl;
    	}
    };
    Person* Person::person = new Person;
    //静态数据成员要在类外初始化
    int main()
    {
    	Person* p = Person::getperson();
    	//这一句得到了:person这个指针成员
    	p->speak();
    	delete p;
    	p = NULL;
    	
    	getchar();
    	getchar();
    	return 0;
    }
    
    

    单例模式分为两种:

    饿汉模式:在初始化的时候就实例化了对象

    懒汉模式:在类中自己提供静态的函数来实例化对象(公有属性)

    class person
    {
    	person()
    	{
    		cout << "我是懒汉模式" << endl;
    	}
    	static person* stance;
    public:
    		static person* getperson()
    	{
    		if (stance == NULL)
    		{
    			stance = new person;
    		}
    		return stance;
    	}
    
    };
    

    二、友元成员

    1、知识点

    1.类的特性之一就是封装,而友元就是c++为用户提供打破这种封装的手段,友元分为友元函数和友元对象

    2、友元函数

    1.友元函数只是一个函数,友元函数不是类的成员,通过类对象是无法访问的,但是在这个函数中有权通过访问类中的成员

    2.友元函数,无论声明在类中的任意访问属性下都可以,不影响他的调用和访问

    #include<iostream>
    #include<string>
    using namespace std;
    class Person
    {
    	int id;
    	string name;
    public:
    	Person(int id, string name)
    	{
    		this->id = id;
    		this->name = name;
    	}
    	//声明友元函数
    	friend void fun();
    	friend void fun1(Person&p);
    };
    
    
    void fun()
    {
    	Person p(1, "yunfei");
    	cout << p.id << endl;
    	cout << p.name << endl;
    }
    void fun1(Person&p)
    {
    	cout << p.id << endl;
    	cout << p.name << endl;
    }
    int main()
    {
    	Person p1(2, "feiyun");
    	fun();
    	fun1(p1);
    	getchar();
    	getchar();
    	return 0;
    }
    
    

    3、友元类

    友元类是一个单独的类,只不过和友元函数一样,在类中声明了一个友元类,在这个友元类中同样也可以访问该类中的所有成员,在A类中声明B类为A类的友元类,那么在B类中就可以访问A类中所有成员

    #include<iostream>
    #include<string>
    using namespace std;
    class girlfriend
    {
    	void sleep()
    	{
    		cout << "一起睡觉" << endl;
    	}
    public:
    	void speak()
    	{
    		cout << "一起说话" << endl;
    	}
    	//声明友元类
    	friend class Boy;
    	//声明了之后,Boy这个类才可以访问girlfriend里的私有属性
    };
    class Boy
    {
    	girlfriend* gf;//要有这个对象才能访问girlfriend这个类
    public:
    	Boy(girlfriend*gf)//构造函数
    	{
    		this->gf = gf;
    	}
    	void sport()
    	{
    		gf->speak();
    		gf->sleep();//声明之后才能访问
    	}
    	~Boy()//析构函数
    	{
    		if (gf != NULL)
    		{
    			delete gf;
    			gf = NULL;
    		}
    	}
    };
    int main()
    {
    	Boy b(new girlfriend);
    	b.sport();
    	getchar();
    	getchar();
    	return 0;
    }
    
    

    4、友元的特性

    1.单方向:B是A的朋友,B可以访问A的数据,A不可以访问B的数据

    2.不传递:A是B的朋友,B是C的朋友,A和C没有朋友关系

    3.不继承:A是B的朋友,B是C的父亲,A和C没有关系

    三、常量成员

    1、知识点

    1.常量成员,指的是在c++类中声明对象成员时可以加上const关键字,这样声明的成员叫常量成员,常量成员分为两类:

    常量数据成员

    常量函数成员

    2、常量数据成员

    //定义
    class node
    {
        const int id;
    }
    //初始化
    const int id=10;//不建议使用,有的版本可能不支持或者通过初始化列表的方式初始化
    

    3、初始化列表的使用

    #include<iostream>
    #include<string>
    using namespace std;
    
    class node
    {
    	//const int id = 10;
    	const int id;
    	int b;
    public:
    	node():id(42),b(99)//初始化列表
    	{
    		b = 34;//最后b=34
    	}//先执行初始化列表,然后执行构造函数
    	int getid()
    	{
    		cout << b << endl;
    		return id;
    	}
    };
    int main()
    {
    	node p;
    	cout << p.getid() << endl;
    	
    	getchar();
    	getchar();
    	return 0;
    }
    
    

    4、初始化列表的特性

    1.初始化列表也是实现类中成员数据的初始化的一种方式

    2.一些特殊情况下,数据成员的初始化只能用初始化列表的方式给数据成员赋值,而不能在构造函数中直接赋值

    3.初始化列表必须写在构造函数的定义后面

    4.构造函数能对数据的初始化工作,初始化列表也可以,但是初始化列表能做的,构造函数不一定能做

    5.初始化列表的初始化顺序是按照他们在类中出现的顺序来初始化的,而不是在初始化列表中写的顺序来初始化的

    构造函数---无参构造,有参构造,拷贝构造

    5、常量函数成员

    1.定义

    class node 
    {
        int id=10;
        public:
        void fun()const
        {
            id=20;//报错
            
            int a;
            a=10;//可以执行
        }
        void fun1()const;//类内声明
    }
    void node::fun1()const//类外实现
    {
        
    }
    //在这个函数中,不能修改类中的数据成员(静态数据可以)
    

    2.特点

    类中的常量函数成员,在这个函数中不能对自身变量进行修改,通过语法限定,只要是this指针所指向的所有数据都不可以被修改(静态数据可以改变)。可以用来帮助我们来限定自身来调用这个函数修改自身的数据

    可以用来只读操作

    6、常量对象

    1.在对象实例化的时候在类名前面加上const修饰,该对象为常量对象,满足常量的操作,声明是必须初始化

    2.该对象里面的所有数据都不能被修改,因此对象里面的普通成员函数不允许被调用,只允许调用常量函数成员

    类中的函数可以写在类外,只需在类中声明即可

    #include<iostream>
    #include<string>
    using namespace std;
    
    class person
    {
    public:
    	person();
    	void fun();
    };
    
    person::person()
    {
    	cout << "这是构造函数" << endl;
    }
    
    void person::fun()
    {
    	cout << "这个是fun函数" << endl;
    }
    int main()
    {
    	person p;
    	p.fun();
    
    	getchar();
    	getchar();
    	return 0;
    }
    
    

    类的分文件编写

    在头文件写下新建,在.h文件下面写函数声明,alt键+enter键,可以定义函数

  • 相关阅读:
    (22)进程和线程区别
    (21)回调函数
    (20)gevent协程
    (18)ProcessPoolExecutor进程池
    (19)ThreadPoolExecutor线程池
    (17)线程队列---queue LifoQueue PriorityQueue
    (16)线程---定时器Timer
    (15)线程---Condition条件
    (14)线程- Event事件和守护线程Daemon
    IDEA快速搭建WEB项目【记录篇】
  • 原文地址:https://www.cnblogs.com/Kissfly123/p/14426207.html
Copyright © 2011-2022 走看看