面向对象知识点1

145 阅读5分钟

# 面向对象基础知识点1

## 一、类和对象
### 第1讲 类的定义及使用
1.类是一种“特殊的数据类型",不是一个具体的数据.
2. 类的构成:方法和数据.
3. 类的设计有public和private
public:共有的、对外的别人可以访问和看到的.
private:私有的只能内部调用和查看,外部不能访问和查看
4.类的定义
#include<Windows.h>
#include<string>

using namespace std;
//定义一个类
class Human{
public:  //共有的、对外的别人可以访问和看到的
	void eat();			//方法,也叫做成员函数
	string getName();	//定义一个字符串

private:		//私有的只能内部调用和观看,外部不能访问和观看
	string name;
};//记得加分号
void Human::eat(){ //重载类的函数
	cout<<"eat food"<<endl;
}
string Human::getName(){//注意返回值类型要与方法一样
	return name;
}
int main(){
	Human zhangsan;	//通过自定义的特殊数据类型“Human”类来创建一个对象
        system("pause");
	return 0;
}

第2讲 对象的基本使用

1.对象是一个特点"类"的具体实例。
2.对象和普通变量的区别。
相对来说,一个对象就是一个特殊的变量,但是有更丰富的功能和用法。
3.对象的具体使用方法

int main(){
	Human zhangsan;	//通过自定义的特殊数据类型“Human”类来创建一个对象
	zhangsan.eat();
	//方法2使用指针创建对象
	Human *p;
	p=&zhangsan;
	p->eat();
	//非法使用
	//cout<<"名字"<<zhangsan.name<<endl;//直接访问私有成员,将无法通过编译
	//正确使用
	//cout<<"名字"<<zhangsan.getName<<endl;//输出值有问,需要用构造函数解决
	system("pause");
	return 0;
}

二、构造函数

第1节 什么是构造函数

构造函数是一种特殊的函数,用来在对象实例化时初始化类的成员的变量。

第2节 构造函数的特点

  1. 在创建对象时,自动调用。
  2. 构造函数的函数名和类名相同。
  3. 构造函数没有返回值。
  4. 可以有多个构造函数。

第3节 构造函数的种类

1)默认构造函数。
2) 自定义的构造函数。
3) 拷贝构造函数。
4) 赋值构造函数。

默认构造函数

没有参数的构造函数即叫做默认构造函数,编译器自动生成的。
1.合成的默认构造函数
没有手动定义默认构造函数时,编译器自动为这个类定义一个构造函数。

1)如果数据成员使用了“类内初始值”,就使用这个值来初始化数据成员。【C++11】

2)否则,就使用默认初始化(实际上,不做任何初始化)
实例1

#include<Windows.h>
#include<string>
using namespace std;
//定义一个类
class Human {
public: //公有的对外的
	void eat(); //方法,成员函数

	string getName();
	int getAge();

private://私有的不对外开放,外部不能查看和访问
	string name;
	int age=22;
};

void Human::eat() {
	cout << "吃炸鸡,喝啤酒!" << endl;
}
string Human::getName() {
	return name;
}
int Human::getAge() {
	return age;
}
int main() {
	Human L1;//使用合成的默认初始化构造函数
	cout << "年龄: " << L1.getAge() << endl;     //使用了类内初始值
	cout << "名字:" << L1.getName() << endl;  //没有类内初始值

	system("pause");
	return 0;
}

结果
年龄: 22
名字:
请按任意键继续. . .
注意:

只要手动定义了任何一个构造函数,编译器就不会生成“合成的默认构造函数”

一般情况下,都应该定义自己的构造函数,不要使用“合成的默认构造函数”

【仅当数据成员全部使用了“类内初始值”,才宜使用“合成的默认构造函数”】

2.手动定义的默认构造函数

test2

#include<Windows.h>
#include<string>
using namespace std;
//定义一个类
class Human {
public: //公有的对外的
	Human();//手动定义的默认构造函数
	void eat(); //方法,成员函数

	string getName();
	int getAge();

private://私有的不对外开放,外部不能查看和访问
	string name;
	int age=22;
};

Human::Human() { //手动定义构造函数
	name = "李汉旭";
	age = 22;
}
void Human::eat() {
	cout << "吃炸鸡,喝啤酒!" << endl;
}
string Human::getName() {
	return name;
}
int Human::getAge() {
	return age;
}

//手动定义的合成默认构造函数
int main() {
		Human L1;//使用合成的默认初始化构造函数
		cout << "年龄: " << L1.getAge() << endl;     
		cout << "名字:" << L1.getName() << endl; 

		system("pause");
		return 0;
	}

结果 年龄: 22
名字:李汉旭
请按任意键继续. . .
说明:如果某数据成员使用类内初始值,同时又在构造函数中进行了初始化,那么以构造函数中的初始化为准。
相当于构造函数中的初始化,会覆盖对应的类内初始值。 自定义的重载构造函数 test3

#include<Windows.h>
#include<string>
using namespace std;
//定义一个类
class Human {
public: //公有的对外的
	Human(int age,string name);//自定义的重载构造函数
	void eat(); //方法,成员函数

	string getName();
	int getAge();

private://私有的不对外开放,外部不能查看和访问
	string name;
	int age = 22;
};

Human::Human(int age,string name) { //手动定义构造函数
	cout << "调用自定义的重载构造函数" << endl;
	this->age = age;	//this是一个特殊的指针指向这个对象本身
	this->name = name;
}
void Human::eat() {
	cout << "吃炸鸡,喝啤酒!" << endl;
}
string Human::getName() {
	return name;
}
int Human::getAge() {
	return age;
}
int main(void) {
	Human  h1(22, "李汉旭");  // 使用自定义的默认构造函数

	cout << "姓名:" << h1.getName() << endl;
	cout << "年龄: " << h1.getAge() << endl;
	

	system("pause");
	return 0;
}

结果
调用自定义的重载构造函数
姓名:李汉旭
年龄: 22
请按任意键继续. . .

拷贝构造函数

test4

1.手动定义的拷贝构造函数
#include<Windows.h>
#include<string>
using namespace std;
//定义一个类
class Human {
public: //公有的对外的
	Human(int age, string name);
	Human(const Human&);
	void eat(); //方法,成员函数

	string getName();
	int getAge();

private://私有的不对外开放,外部不能查看和访问
	string name;
	int age = 22;
};
Human::Human(int age, string name) {
	cout << "调用自定义的构造函数" << endl;
	this->age = age;      //this是一个特殊的指针,指向这个对象本身
	this->name = name;
	name = "无名";
}
Human::Human(const Human& man) {
	cout << "调用自定义的拷贝构造函数" << endl;
	name = man.name;
	age = man.age;
}
void Human::eat() {
	cout << "吃炸鸡,喝啤酒!" << endl;
}
string Human::getName() {
	return name;
}
int Human::getAge() {
	return age;
}
int main(void) {
	Human  h1(22, "李汉旭");  // 使用自定义的默认构造函数
	Human  h2(h1);  // 使用自定义的拷贝构造函数
	cout << "姓名:" << h2.getName() << endl;
	cout << "年龄: " << h2.getAge() << endl;


	system("pause");
	return 0;
}
拷贝构造函数,浅拷贝与深拷贝的区别

[(拷贝构造函数 浅拷贝与深拷贝 - 掘金 (juejin.cn))]

什么时候调用拷贝构造函数****

什么时候调用拷贝构造函数

1. 调用函数时,实参是对象,形参不是引用类型

   如果函数的形参是引用类型,就不会调用拷贝构造函数

2. 函数的返回类型是类,而且不是引用类型

3. 对象数组的初始化列表中,使用对象。

拷贝构造函数与赋值构造函数的差别

析构函数

作用:

对象销毁前,做清理工作。

具体的清理工作,一般和构造函数对应

比如:如果在构造函数中,使用new分配了内存,就需在析构函数中用delete释放。

如果构造函数中没有申请资源(主要是内存资源),

那么很少使用析构函数。

函数名::~类型

没有返回值,没有参数,最多只能有一个析构函数

访问权限:

一般都使用public

使用方法:

不能主动调用。

对象销毁时,自动调用。

如果不定义,编译器会自动生成一个析构函数(什么也不做)