c++~第4课-----特殊成员

目录

const成员

static成员

友元

this指针与explicit


const成员

  • const数据成员

const类型变量是不可以修改,只读模式

必须采用初始化参数列表方式初始化

  • const成员函数

写法上,const写在函数后面

常成员函数是不能够修改数据成员,只读数据成员

常成员函数可以和普通函数同时存在

普通对象和常成员函数同时存在,普通对象优先调用普通函数

普通对象可以调用常成员函数

//同时存在
class MM
{
  void print()
	{
		//num = 0;//错误,不能修改只读模式
		cout <<"普通函数"<< endl;
	}
	void print()const
	{
		//name = "修改";//不能修改
		//num = 9;
		cout << "const成员函数" << endl;
	}
}
int main()
{
	MM mm("你好", 11);
	mm.print();

	return 0;
}

  • const对象

const修饰的对象

常对象只能调用常成员函数

#include <iostream>
#include <string>
using namespace std;
class MM
{
public:
	MM(string name, int num) :num(num)
	{
		//MM::num = 0;不能直接在里面初始化必须要参数列表
		MM::name = name;//可以不用,可以用初始化参数列表
	}
	void print()
	{
		//num = 0;//错误,不能修改只读模式
		cout <<"普通函数" << endl;
	}
	//常成员函数
	void print()const
	{
		//name = "修改";//不能修改
		//num = 9;
		cout << "const成员函数" << endl;
	}
	void print2()
	{
		//num = 0;//错误,不能修改只读模式
		cout << "普通函数" << endl;
	}
protected:
	string name;
	const int num;//const数据成员
};
int main()
{
	MM mm("你好", 11);
	mm.print();//普通对象调用普通函数
	const MM mm2("常对象", 111);
	mm2.print();//常对象调用常成员函数
	//mm2.print2();//错误,常对象只能调用常成员函数

	return 0;
}

static成员

static成员不属于对象,是属于类的,意味着是所有对象共有的,调用可以不需要对象,也开头用对象调用,static成员依旧受权限限定

  • static数据成员

必须在类外初始化,类外初始化,不再需要static修饰,但是需要类名限定

类中初始化是错误的,以及不能采用初始化参数列表初始化

#include <iostream>
#include <string>
using namespace std;
class MM
{
public:
	MM(string name=" ")
	{
		num++;
	}
protected:
	string name;
public://需要把权限改成公有
	static int num;
	//static int num=0;//类中初始化是错误的
};
//类外初始化,不再需要static修饰,但是需要类名限定
int MM::num = 1001;
int main()
{
	//静态成员成员访问,可以不需要对象
	cout << MM::num << endl;//1001
	//什么叫共有?
	MM mm("mm");
	//静态数据成员可以通过对象去访问
	cout << mm.num << endl;//此时num=1002
	MM arr[4];
	MM* p = new MM("newNum");
	cout << MM::num << endl;//1007
	cout << p->num << endl;//1007
	cout << mm.num << endl;//1007
	delete p;
	p = nullptr;


	return 0;
}
  • static成员函数

static写在函数前面,调用非静态成员必须指定对象

#include <iostream>
#include <string>
using namespace std;
class MM
{
public:
	MM(string name=" ")
	{
		num++;
	}
	static void printData();
	static void printData2(MM& mm)
	{
		cout << mm.name << " " << mm.num << endl;
	}
protected:
	string name="你好";
public://需要把权限改成公有
	static int num;
	//static int num=0;//类中初始化是错误的
};
//类外初始化,不再需要static修饰,但是需要类名限定
int MM::num = 1001;
void MM::printData()
{
	//调用非静态成员必须要指定对象
	//cout << name << endl;//当这个函数不采用对象去调用,name没有来源
	cout << num << endl;//静态函数调用静态数据,没什么要求
	cout << "非静态成员" << endl;
}

int main()
{
	//静态成员成员访问,可以不需要对象
	cout << MM::num << endl;//1001
	//什么叫共有?
	MM mm("mm");
	//静态数据成员可以通过对象去访问
	cout << mm.num << endl;//此时num=1002
	MM arr[4];
	MM* p = new MM("newNum");
	cout << MM::num << endl;//1007
	cout << p->num << endl;//1007
	cout << mm.num << endl;//1007
	delete p;
	p = nullptr;
	mm.printData2(mm);
	MM::printData2(mm);
	

	return 0;
}

  • static对象

释放是最后释放的

友元

用friend描述的关系,友元只是提供一个场所,赋予对象具有打破类的权限限定(无视权限)

  • 友元函数

普通友元函数充当友元函数

#include <iostream>
#include <string>
using namespace std;
void printData();
class MM
{
public:
	MM(string name, int age) :name(name), age(age)
	{

	}
	void print()
	{
		cout << name << " " << age << endl;
	}
	friend void printData()//无参的友元函数类中实现需要前面声明
	{
		//cout << name << age << endl;//错误的不属于类,不能直接访问成员
		MM m2("无视权限", 14);
		//友元函数提供一个场所,让对象无视权限
		cout << m2.name << " " << m2.age << endl;
	}
protected:
	string name;
private:
	int age;
	friend void printData2(MM& mm);
};
//类外实现不需要friend修饰,不需要类名限定
void printData2(MM& mm)
{
	cout << mm.name << mm.age << endl;
}


int main()
{
	MM mm("美女", 18);
	mm.print();
	printData2(mm);//直接调用
	printData();

	return 0;
}

以另一个类的成员函数

步骤:B类-->A类---->A类的友元函数(B类的成员函数)

//类外实现不需要friend修饰,不需要类名限定
void printData2(MM& mm)
{
	cout << mm.name << mm.age << endl;
}

class B
{
public:
	void printA();

protected:
};
class A
{
public:
	friend void B::printA();
protected:
	string name = "a";
};

//成员函数实现,一定是另一个类的下面实现
void B::printA()
{
	A a;
	cout << a.name << endl;
}
int main()
{
	
	B b;
	b.printA();//输出a
	return 0;
}
  • 友元类
#include <iostream>
#include <string>
using namespace std;

class MM
{
	friend class GG;
public:
	MM(string name, int age) :name(name), age(age)
	{
		
	}

protected:
	string name;
	int age;

};
class GG
{
public:
	void print()
	{
		MM mm("你好", 14);
		cout << mm.name << " " << mm.age;
	}
	void print2(MM& mm)
	{
		cout << mm.name << " " << mm.age;
	}
	MM& returnMM(MM& mm)
	{
		return mm;
	}
protected:

};
int main()
{
	MM mm("阿拉蕾", 444);
	GG gg;
	gg.print();
	gg.print2(mm);
	//cout<< gg.returnMM(mm) << endl;//错误,出了友元类,没有权限
	return 0;
}

互为友元

#include <iostream>
#include <string>
using namespace std;
//互为友元
class A
{
	friend class B;
public:
	void print();
protected:
	string data = "A";
};

class B
{
public:
	friend class A;
	void print()
	{
		A a;
		cout << a.data << endl;
	}
protected:
	string data = "B";
};
void A::print()
{
	B b;
	cout << b.data << endl;
}
int main()
{
	B b;
	b.print();
	A a;
	a.print();
	return 0;
}

this指针与explicit

  • explicit修饰构造函数使用,不让隐式转换构造
#include <iostream>
using namespace std;

class MM
{
public:
	explicit MM(int age) :age(age)
	{
		cout << age << endl;
	}
protected:
	int age;
};
int main()
{
	//隐式构造函数
	//explicit限制隐式构造
	MM mm = 111;
	MM mm = 1.23;//会自动把小数隐式转换成整数
	return 0;
}
  • this指针

避免形参名和数据成员同名,通指对象的地址,类外是没有this指针

充当函数返回值,返回对象本身,用*this表示对象本身.

静态成员函数中是不能使用this指针的

#include <iostream>
using namespace std;

class MM
{
public:
	 MM(int age) :age(age){}
	 //普通函数不存在初始化参数列表
	// void initData(int age) : age(age){}//错误写法
	 void initData(int age)
	 {
		 MM::age=age;//类名限定方式,帮助计算机识别
		 this->age=age;//this指针方式
	 }
	 void print()
	 {
		 cout << this->age << endl;
	 }
	 MM returnMM()
	 {
		 return *this;//返回对象本身
	 }
	 //这种写法错误的,static没有this指针
	/*static MM rerurnMM2()
	 {
		cout << this->age << endl;
	 }*/

protected:
	int age;
};
int main()
{
	MM mm(111);
	mm.print();
	mm.initData(222);
	mm.print();
	mm.returnMM().print();
	
	return 0;
}

 实现string

#include <iostream>
#include <string>
#include <cstring>
using namespace std;
class mystring
{
public:
	mystring(const char* str=" ")
	{
		strSize = strlen(str) + 1;
		mystring::str = new char[strSize];
		strcpy_s(this->str,strSize, str);
	}
	mystring(const mystring& object)
	{
		strSize = object.strSize;
		str = new char[strSize];
		strcpy_s(str, strSize, object.str);
	}
	char* c_str()
	{
		return str;
	}
	char* data()
	{
		return str;
	}
	mystring append(const mystring& object)
	{
		mystring temp;
		temp.strSize = mystring::strSize + object.strSize-1;
		temp.str = new char[temp.strSize];
		memset(temp.str, 0, temp.strSize);
		strcat_s(temp.str, temp.strSize, str);
		strcat_s(temp.str, temp.strSize, object.str);
		return temp;
	}
	int compare(const mystring& object)
	{
		return strcmp(str, object.str);
	}
	~mystring()
	{
		delete[] str;
		str = nullptr;
	}

protected:
	char* str;
	int strSize;
};


int main()
{
	//1.实现string中创建方式
	mystring str1;
	mystring str2("ILOVEYOU");
	mystring str3(str1);
	mystring str4 = str2;
	//2.通过实现data和c_str函数  打印字符串
	cout << str2.c_str() << endl;//打印ILOVEYOU
	cout << str2.data() << endl;//打印ILOVEYOU
	//3.实现append实现字符串的连接
	mystring strOne = "one";
	mystring strTwo = "two";
	mystring strThree = strOne.append(strTwo);
	cout << strThree.data() << endl;//onetwo
	//实现字符串比较
	cout << strOne.compare(strOne) << endl;//0
	//5.手写构造函数释放内存



	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Luckys-Yang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值