C++小知识点(三)------C++ primer plus中文版(第六版)

1、过程性编程和面向对象编程

1、	过程性编程思想:把问题拆分成一步步来完成,是自顶向下逐步求精,其最重要的是模块化的思想方法。
2、	面向对象编程思想:把问题看作一个个对象,然后由对象之间分工合作。
	总结:面向对象是以对象功能来划分问题,而不是步骤(描述对象的数据和对数据交互所需的操作);

参考链接

2、抽象和类

2.1、什么是类型:

在程序中指定的数据类型,表明:
1、	决定数据对象需要的内存数量;
2、	决定如何解释内存中的位;
3、	决定可使用数据对象执行的操作或方法;
总结:因此在C++中自己定义数据类型的同时,需要提供处理这些数据类型的方法。

2.2、什么是类:

1、	类是一种将抽象转换为用户定义类型的C++工具,它将数据表示和操纵数据的方法组合成一个整洁的包。
2、	类的组成:类声明 + 类方法定义。
	类声明:数据成员和成员函数(其中方法称为公有接口),一般放在头文件中;
	类方法定义:如何实现类成员函数;一般在源代码文件。

2.3、访问控制:

使用关键字:public、private,描述了对类中的成员的访问控制。

1public表示公有成员(成员函数)
2private表示私有成员(数据成员)------不加任何关键字时,为默认访问控制
	一般我们将类数据成员设为private,而成员函数设置为public,这是因为使用类对象的程序可直接访问公有部分,而不能访问私有部分,
	将成员函数设置为public,使得只能通过成员函数对数据成员进行操作,可以防止程序直接对数据操作,此时公有成员函数成了程序和对象
	私有数据成员之间的桥梁。

公有成员函数可以访问对象的私有成员,将数据封装到私有部分,可以保护数据的完整性,这成为数据隐藏。

2.4、类的使用:

由上述2.2可知,类声明和类成员函数定义是分开的,那么类成员函数定义该如何写?

1、类声明:
class Student			习惯首字母大写
{
private:
	string name;
	string address;
	int age;
public:
	void Show_addr();
};									注意结尾有分号

2、类成员函数定义:	这里使用作用域解析运算符::,表明该函数属于类Student
void Student::Show_addr()
{
	//operation
}

3、如何调用类的公有成员函数(使用成员运算符)
	Student fhl;					创建类对象
	fhl.Show_addr();				调用成员函数

4、不同类的类数据成员和成员函数都占据空间嘛?
	不是的,创建的类对象都有自己的存储空间,但类对象的数据成员分别占据不同的内存块,而所有类对象共享同一组类方法。
	Student fhl, wy;						创建了两个Student对象
	fhl.name 和 wy.name						占据不同内存块
	fhl.Show_addr() 和 wy.Show_addr()		指向同一个代码块,只是这些代码用于不同的数据

3、构造函数和析构函数

3.1、为什么需要构造函数和析构函数?

我们创建类对象的初衷是为了像其他类型一样(int、struct、char),但是到目前为止,还不允许下列操作:

class Student
{
private:
	string name;
	string address;
	int age;
public:
	void Show_addr();
};

int value = 10;								valid
Student fhl = {"xiaofang",23,"hubei"};		invalid,因为前面提过,不允许直接访问数据成员

正如上面所说,不允许我们直接对数据成员操作,因此需要设计合适的成员函数,才可以对对象初始化,这就是构造函数。
构造函数:构造类对象时,自动调用一次构造函数,将值赋给数据成员来完成初始化

1、	构造函数的声明和定义:构造函数和类名一致
	构造函数的定义可以放在类声明的公有部分,也可以放在外部(此时需要加上 类名::类名)
	放在公有部分时:
	class Student
	{
	private:
		string name;
		string address;
		int age;
	public:
		构造函数的声明,可以放在公有部分,无返回值,可以使用默认参数
		Student(const string t_name, string t_addr, int t_age = 26);
		void Show_addr();
	};
	
	构造函数的定义:在类声明的外部使用::
	Student::Student(const string t_name, string t_addr, int t_age)
	{
		name = t_name;
		address = t_addr;
		age = t_age;
	}
	
2、构造函数的声明和定义放在一起
	class Student
	{
	private:
		string name;
		string address;
		int age;
	public:
		构造函数的声明,可以放在公有部分,无返回值,可以使用默认参数
		Student(const string t_name, string t_addr, int t_age)
		{
			name = t_name;
			address = t_addr;
			age = t_age;
		}
		void Show_addr();
	};

3.2、构造函数的使用

class Student
	{
	private:
		string name;
		string address;
		int age;
	public:
		构造函数的声明,可以放在公有部分,无返回值,可以使用默认参数
		Student(const string t_name, string t_addr, int t_age = 26);
		void Show_addr();
	};
	
	构造函数的定义:在类声明的外部使用::
	Student::Student(const string t_name, string t_addr, int t_age)
	{
		name = t_name;
		address = t_addr;
		age = t_age;
	}
	
1、	显示调用构造函数
	Student fhl = Student("xiaofang","hubei",26);
2、	隐式调用构造函数
	Student fhl("xiaofang","hubei",26);

3.3、默认构造函数

1、什么是默认构造函数?
在未提供显示初始值时,用来创建对象,也就是说如果我们没有提供任何的构造函数,在创建对象时,C++将自动提供构造函数,只是这个构造函数为空实现。
当且仅当没有定义任何构造函数时,编译器才会提供默认构造函数,但当定义了构造函数后,必须提供一个默认构造函数,也就是说一般提供两个构造函数:一个是默认构造函数(不带任何参数);一个是自己定义的带参数的构造函数,这符合函数重载的条件。

2、为什么需要默认构造函数?
主要是为了禁止创建未初始化的对象

默认构造函数的定义方法:
1、	所有参数为默认值
	class Student
	{
	private:
		string name;
		string address;
		int age;
	public:
		Student(const string t_name = "temp_name", string t_addr = "temp_addr", int t_age = 0);
		void Show_addr();
	};

	Student::Student(const string t_name, string t_addr,int t_age)
	{
		name = t_name;
		address = t_addr;
		age = t_age;
	}
	
2、	不带任何参数
	class Student
	{
	private:
		string name;
		string address;
		int age;
	public:
		Student();
		void Show_addr();
	};

	Student::Student()
	{
		name = "temp_name";
		address = "temp_addr";
		age = 0;
	}

上述默认构造函数选择一种使用即可,在有了上述的构造函数之后,就可以只创建对象,而不初始化,因此此时会自动调用默认构造函数完成初始化

Student fhl;					隐式调用默认构造函数
Student fhl = Student();		显示调用默认构造函数

3.4、析构函数

1、什么是析构函数?
构造函数是创建对象,而析构函数就是对象过期时,使用析构函数来清理对象,同样也是自动调用。

1、	析构函数语法:~类名();			无返回值和参数,无法重载
2、	由于析构函数不承担重要的工作,因此可以为空实现
	Student::~Student()
	{
		
	}

3.5、析构函数的使用

1、由上面分析可知,析构函数是对象过期时,来清理对象的,但是我们需要搞清楚析构函数的调用顺序。
2、初始化和赋值操作的区别。

	class Student
	{
	private:
		string name;
		string address;
		int age;
	public:
		Student(const string t_name, string t_addr, int t_age);		普通构造函数
		Student();													默认构造函数
		~Student();													析构函数
		void Showmessage();
	};
	
	Student::Student(const string t_name, string t_addr, int t_age)
	{
		name = t_name;
		address = t_addr;
		age = t_age;
	}
	
	Student::Student()
	{
		name = "temp_name";
		address = "temp_addr";
		age = 0;
	}

	Student::~Student()
	{
		cout << "Bye, " << name << endl;
	}
	
1、	对于我们创建的局部对象来说,也是放在栈中的,因此符合后创建先删除
2、	初始化可能创造临时对象,而对已有对象的赋值操作会创建临时对象
	int main()
	{
		1、初始化
		Student fhl = Student{"xiaofang", "hubei1", 26};			先创建,后析构
		Student wy = Student{"xiaowu", "hubei1", 24};				后创建,先析构

		2、赋值操作
		fhl = Student("dafang", "beijing", 25);				对已有对象的再此赋值操作,会在赋值前有一个创建临时对象的操作。
		return 0;
	}
	
	result:
	bye,dafang
	bye,xiaowu
	bye,dafang

3.6、其他知识点

1、对象初始化的几种方法:

	class Student
	{
	private:
		string name;
		string address;
		int age;
	public:
		Student(const string t_name, string t_addr, int t_age);		普通构造函数
		Student();													默认构造函数
		~Student();													析构函数
		void Showmessage();
	};
	
	Student::Student(const string t_name, string t_addr, int t_age)
	{
		name = t_name;
		address = t_addr;
		age = t_age;
	}
	
	Student::Student()
	{
		name = "temp_name";
		address = "temp_addr";
		age = 0;
	}

	Student::~Student()
	{

	}
	
1、	Student fhl = Student{"xiaofang", "hubei1", 26};		普通构造函数的显示调用
2、	Student fhl{"xiaofang", "hubei1", 26};					普通构造函数的隐式调用
3、	Student fhl = {"xiaofang", "hubei1", 26};				普通构造函数的列表初始化方法
4、	Student fhl = Student();								默认构造函数的显示调用
5、	Student fhl;											默认构造函数的隐式调用

2、const对象和成员函数

const Student fhl = Student{"xiaofang", "hubei1", 26};			const对象
fhl.Showmessage();												不被允许,因为Showmessage函数可能修改const对象

解决办法:将const放在函数()的后面
class Student
	{
	private:
		string name;
		string address;
		int age;
	public:
		Student(const string t_name, string t_addr, int t_age);		普通构造函数
		Student();													默认构造函数
		~Student();													析构函数
		void Showmessage() const;									const成员函数
	};

	void Student::Showmessage() const
	{
		cout << "姓名为:" << name << endl;
		cout << "地址为:" << address << endl;
		cout << "年龄为:" << age << endl;
	}

3.7、构造函数和析构函数小结

一、构造函数语法:类名(){}
1. 构造函数,没有返回值也不写void
2. 函数名称与类名相同
3. 构造函数可以有参数(也可以没有参数),因此可以发生重载
4. 程序在调用对象时候会自动调用构造,无须手动调用,而且只会调用一次

析构函数语法: ~类名(){}
1. 析构函数,没有返回值也不写void
2. 函数名称与类名相同,在名称前加上符号 ~
3. 析构函数不可以有参数,因此不可以发生重载
4. 程序在对象销毁前会自动调用析构,无须手动调用,而且只会调用一次

构造函数允许函数重载,允许有多个构造函数存在:默认构造函数、普通构造函数
析构函数不允许重载,有且仅有一个
构造函数使用了new,则在析构函数中必须有delete
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值