c++的类与对象(下)

1.初始化列表
在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值,构造函数体中的语句只能将其称作为赋初值,而不能称作初始化,因为初始化只能初始化一次(初始化的本质就是只能初始化一次),而构造函数体内可以多次赋值
①.以一个冒号开始:接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括号中的初始值或者表达式
②.初始化列表是每个成员定义的地方,不管你写不写,每个成员都要走初始化列表,不写的话,内置类型为随机值,自定义类型会调用默认构造
③.在声明给值是缺省值而非定义,这个缺省值是给初始化列表用的,如果初始化列表没有显式给值,就用这个缺省值,如果显式给值,就不用这个缺省值
④.每个成员在初始化列表中只能出现一次(初始化只能初始化一次)
⑤.类中包含以下成员,必须在初始化列表位置进行初始化
引用成员变量 - 引用必须在定义的时候初始化,而初始化列表是每个成员定义的地方
const成员变量 -const常量必须在定义的时候初始化
自定义类型成员(该类没有默认构造函数)
⑥.成员变量在类中的声明顺序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关
2.explicit关键字
构造函数不仅可以构造与初始化对象,对于单个参数的构造函数,还具有类型转换的作用

A aa2=2;
//用2构造一个临时对象,再用这个临时对象拷贝构造aa2
//但编译器会优化,直接用2构造对象,只需要调用一次构造函数,而不用先调用构造函数再拷贝构造
const A&ref=2;
//必须用const修饰,因为2会生成一个临时变量,临时变量具有常性

类似

int i=0;
double d=1.1;
i=d;
//中间会生成一个临时变量

c++11支持多参数的转换

B bb2={2,2};
const B&ref={3,3};

如果用explicit修饰构造函数,将会禁止单参构造函数的隐式转换
3.static成员
声明为static的类成员称为类的静态成员,用static修饰的成员变量,称为静态成员变量,用static修饰的成员函数,称为静态成员函数,静态的成员变量一定要在类外进行初始化
①.静态成员为所有类所共享,不属于某个具体的实例(静态成员变量属于整个类)
②.静态成员变量必须在类外定义,定义时不添加static关键字
在类内 static int n;
类外 int A::n=0;
③.类静态成员既可用类名::静态成员 也可以用对象.静态成员来访问
④.静态成员函数没有隐藏的this指针不能访问任何非静态成员
⑤.静态成员与类的普通成员一样,也有public,private,protected3种访问级别,也可以具有返回值
A*ptr=nullptr;
cout<n<m<<endl;
这里ptr->n,虽然ptr是空指针,但是n是静态成员变量,与用空指针调用成员函数一样,都是可以的
有没有解引用,不能看形态,要看存放的位置
static int&getm(){
return m;}
用引用返回,可以修改m
++A::getm();
私有与保护限制的是不能在类外访问,但是这个函数返回m不受影响

实现一个类,计算程序中创建出了多少个类对象

class A{
	public:
		A(){
			++n;
			++m;
		}
		A(const A&t){
			++n;
			++m;
		}
		~A(){
			--n;
		}
		private:
		int m;
		int n;
};

m代表一共创建了多少对象
n代表目前还有多少对象

求1+2+3+…+n,要求不能使用乘除法,for,while,if else,Switch case,位运算

class solution{
	class sum{
		public:
			sum(){
				_ret+=i;
				_i+=1;
			} 
	};
	public:
		int getsum(int n){
			sum a[n];
			return _ret; 
		}
	private:
	  	static int _ret;
		static int _i;	
};
int solution::_ret=1;
int solution::_i=0;

4.友元
友元分为:友元函数和友元类
友元函数提供了一种突破封装的方式,有时提供了便利,但是友元会增加耦合度,破坏了封装,所以友元不宜多用。

友元函数

比如之前想要重载<<符号,cout的输出流对象和隐藏的this指针都在抢第一个参数的位置,this指针默认是第一个参数,但如果构造正常函数,将this指针放在第二个参数,会导致类外无法访问私有成员,故采用友元
友元函数可以直接访问类的私有成员和保护成员,它是定义在类外的普通函数,不属于任何类,不是类的成员函数,但需要在类的内部声明,声明时需要加friend关键字
①.友元函数不能用const修饰,静态成员函数也不能用const修饰,因为const修饰的实质上是形参this指针,而友元函数和静态成员函数都没有this指针
②.友元函数可以在类定义的任何地方声明,不受类访问限定符的限制
③.一个函数可以是多个函数的友元函数
④.友元函数的调用与普通函数的调用和原理相同

友元类
①.友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类的非公有成员
②.友元类是单向的,不具有交换性
③.在time类中声明date类为其友元类,那么可以在date类中直接访问time类的私有成员变量,但不能在time类中访问date类的私有成员变量
④.友元关系不能传递,如果B是A的友元,C是B的友元,不能说C是A的友元

class Date;//前置声明
class Time;
{
	friend class Date;//声明Date类是Time类的友元类,可以在Date类中直接访问Time类的私有成员变量
	public:
		Time(int hour,int minute,int second)
	    :_hour(hour)
	    ,_minute(minute);
	    ,_second(second);
	    {}
	private:
		int _hour;
		int _minute;
		int _second;
};
class Date{
	public:
		Date(int year=1900,int month=1,int day=1)
			:_year(year);
			,_month(month);
			,_day(day);
			{}
			void settimeofdate(int hour,int minute,int second){
				_t.hour=hour;
				_t.minute=minute;
				_t.second=second;//因为已经声明了Date类为Time类的友元类,故Date类可以访问Time类的私有成员变量
			}
		private:
			int _year;
			int _month;
			int _day;
			Time _t;		
};

5.内部类
如果一个类定义在另一个类的内部,这个内部类就叫做内部类,此时内部类是一个独立的类,不属于外部类,不能通过外部类的对象去调用内部类,外部类对内部类没有任何优越的访问权限
内部类是外部类的友元类,内部类可以通过外部类的对象参数来访问外部类中的所有成员,但是外部类不是内部类的友元(友元关系不具有交换性)
①.内部类可以定义在外部类的Public,protected,private都是可以的
②.内部类可以直接访问外部类的static,枚举成员,不需要外部类的对象/类名
③.sizeof(外部类)=外部类,和内部类没有任何关系

#include <iostream>
using namespace std;
class A{
	private:
		static int k;
		int h;
		public:
			class B{
				public:
				void fun(){
                    k=1;//内部类可以直接访问外部类的static,不需要对象名/类名
					A aa1;
					aa._h=1;//内部类是外部类的友元类,可以访问外部类的私有成员变量
				}
			};
};
int A::k=0;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值