C++ 类(static, const,内联函数等)

this

C++编译器给每个“非静态的成员函数“增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有成员变量的操作,都是通过该指针去访问。
this指针的类型:类型 *const
只能在类的“成员函数”的内部使用
this指针本质上其实是一个成员函数的形参,是对象调用成员函数时,将对象地址作为实参传递给this形参。所以对象中不存储this指针。

类的6个默认成员函数

任何一个类在我们不写的情况下,都会自动生成下面6个默认成员函数。

  1. 构造函数主要完成类的初始化工作(实例化对象)构造函数可以重载
  2. 析构函数主要完成对象清理工作
  3. 拷贝构造函数是使用同类对象初始化创建对象
    拷贝构造函数是构造函数的一个重载形式。
    拷贝构造函数的参数只有一个且必须使用引用传参,使用传值方式会引发无穷递归调用。
    编译器生成的默认拷贝构造函数已经可以完成字节序的值拷贝了,在特定情况下,当类里面的成员变量包含有指针的时候,我们仍需自己实现,用于解决浅拷贝带来的内存多次问题。
    成员函数不以引用(&)传递类对象参数将会调用拷贝构造函数
  4. 赋值语句主要是把一个对象赋值给另一个对象
    赋值运算符主要有四点:
    参数类型
    返回值
    检测是否自己给自己赋值
    返回*this
    同样我们需要实现赋值语句,避免浅拷贝带来的问题。
  5. 6.取地址重载,主要是普通对象和const对象取地址。
class Date
{
	public :
	Date* operator&()   //普通对象取地址重载
	{
		return this ;
	}
	const Date* operator&()const //const对象取地址重载
	{
		return this ;
	}
class Data
{
	//构造
	Data(){}
	//拷贝构造
	Data(const Date& d){}
	
};

void main()
{
	//如果用户显式定义了构造函数,编译器将不再生成默认构造函数
	Data d1;  //无参构造函数,对象后面不跟括号,否则成为函数声明。
	Data d2 = d1;//Data d2(d1)  拷贝构造函数

	Data d3;
	d3 = d1; //赋值语句
	//声明了d3函数,该函数无参,返回一个日期类型的对象
	Date d3();
}

运算符重载

C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数也具有其返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。
返回值类型 operator操作符(参数列表)
不能通过连接其他符号来创建新的操作符
用于内置类型的操作符,其含义不能改变,例如:内置的整型+,不 能改变其含义
不能重载的运算符 ::(作用域限定符) sizeof, ?:(三目运算符), .(点号运算符)

const成员

const * 三种情况

  1. int const * p 封锁*p为常量,p指针指向的值为常量 *p不能改 p可以改
  2. int * const p p被修饰为常量,p不可以被更改, 但是*p可以更该 *p可以改 p不能改
  3. int const * const p和*p都不能被修改 *p 和 p 都不能改
void main()
{
	int a = 4;
	int b = 10;
	//1.
	const int *p;
	int const *p;

	//2.
	int * const p = &a; 
	//3.
	const int * const p = &a;
}

void main()
{
	const int a = 4;
	//int *p = &a; //错误
	const int *p = &a; //正确
}
class Date
{
public:
	void Display()
	{
		cout << "Display ()" << endl;
	}
	void Display() const
	{
		cout << "Display () const" << endl;
		//Date::Show(); const成员函数内不可以调用其它的非const成员函数。
	}
	void Set()const
	{
		cout << "Set" << endl;
	}
	void Show()
	{
		cout << "Show" << endl;
		Date::Set(); //非const成员函数内可以调用其它的const成员函数
	}
	void Get()const
	{
		cout << "Get" << endl;
	}
};
void main()
{
	Date d1;
	d1.Get();//非const对象可以调用const成员函数
	d1.Display();
	const Date d2;   //const对象调用const成员函数
	d2.Display();
//	d2.Show();//const对象不能调用非const成员函数
}

友元类和友元函数

友元提供了一种突破封装的方式,有时提供了便利。不宜多用
重载operator<<, operator>>友元使用较多

友元函数
友元函数可访问类的私有和保护成员,但不是类的成员函数
友元函数不能用const修饰
友元函数可以在类定义的任何地方声明,不受类访问限定符限制
一个函数可以是多个类的友元函数
友元函数的调用与普通函数的调用和原理相同
友元类
友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。
友元关系是单向的,不具有交换性。
友元关系不能传递

ostream& operator<<(ostream& cout, const Data& d)
{
	cout<<d.val;
	return cout;
}
istream& operator>>(istream &in,  Data& d)  
{
	in>>d.val;
	return in;
}

内部类

如果一个类定义在另一个类的内部,这个内部类就叫做内部类。
这个内部类是一个独立的类,它不属于外部类,更不能通过外部类的对象去调用内部类。
内部类就是外部类的友元类,但是外部类不是内部类的友元
内部类可以通过外部类的对象参数来访问外部类中
的所有成员。
注意内部类可以直接访问外部类中的static、枚举成员,不需要外部类的对象/类名
sizeof(外部类)=外部类,和内部类没有任何关系

static

static修饰的成员变量,称之为静态成员变量, 静态的成员变量一定要在类外进行初始化,且所有对象共享。不属于任何一个对象。可以通过对象和类名调用
用static修饰的成员函数,称之为静态成员函数,只属于类,使用时必须用类名加作用域限定符和函数名调用。不包含this指针。不能访问非静态成员。

class A
{
public:
	static void show()
	{
		cout << "show" << endl;
		/*get();*/ //静态函数无法调用非静态函数,由于没有this指针
	}
	void get()
	{
		cout << "get" << endl;
		show(); //非静态函数可以调用静态函数
	}
};

内联函数

以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数压栈的开销,内联函数提升程序运行的效率。
适用于短小精悍的代码 类似于宏 是一种声明 inline,对于有循环,递归的代码不适用于内联
内联函数 不能分离实现, 如 在一个文件声明 另一个文件实现, 是不可行的
宏的优缺点?
优点:
1.增强代码的复用性。
2.提高性能。
缺点:
1.不方便调试宏。(因为预编译阶段进行了替换), 严格的替换
2.导致代码可读性差,可维护性差,容易误用。
3.没有类型安全的检查 。
C++有哪些技术替代宏?

  1. 常量定义 换用const
  2. 函数定义 换用内联函数

explicit关键字

用explicit修饰构造函数,将会禁止单参构造函数的隐式转换。但是仍然可以显式转换。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值