C++ 类和对象

一、成员函数

可以在类里面定义,也可以在类外面定义。

class Student {
public:
	string name;
	int age;
	char gender;

	void show1() {
		cout << "(" << name << ", " << age << ", " << gender << ")" << endl;
	}
	void show2();
};
void Student::show2() {
	cout << "(" << name << ", " << age << ", " << gender << ")" << endl;
}

调用方式:

Student s1;
s1.name = "XX";
s1.show1();

二、构造函数(重点)

如果你在类里面不添加构造函数和析构函数,c++会给你默认添加3种函数,默认构造函数、拷贝构造函数和析构函数。

如果你添加了带参数的构造函数或拷贝构造函数,那么c++就不会给你自动添加默认构造函数,所以用的时候最好把默认构造函数也加上。

1、默认构造函数

class Student {
public:
	int id;
	Student() {
		id = 0;
		cout << "Student()" << endl;
	}
};

2、带参数的构造函数

Student(int _id) {
	id = _id;
	cout << "Student(int _id)" << endl;
}

3、拷贝构造函数

Student(const Student& s) {
	id = s.id;
	cout << "Student(const Student & s)" << endl;
	//前面加个const是为了避免拷贝进去之后被修改
}

4、构造函数的调用方法

Student s1;//默认
Student s2 = Student();//默认
Student s3 = {};//默认
Student s4(1);//带参数
Student s5 = Student(1);//带参数
Student s6 = { 1 };//带参数
Student s7(s1);//拷贝
Student s8 = Student(s1);//拷贝
Student s9 = { s1 };//拷贝
Student s10 = s1;//Student s10 = Student(s1);

下面的形式是错误的:

Student s1();//Declare a function
Student (s1);//不能单独把构造函数拿出来

三、析构函数(重点)

析构函数不接受参数。

class Student {
public:
	int id;
	Student() {
		id = 0;
		cout << "Student()" << endl;
	}
	~Student() {
		cout << "~Student()" << endl;
	}
};
int* test1() {
	Student s = Student();
	return &s.id;
}

如果main函数如下,则调用了析构函数:

void main() {
	int* id = test1();//调用完该函数就出了作用域,析构
	cout << *id << endl;//出错,已经被析构,访问不到
	system("pause");
}

如果如下,则没有调用析构函数:

void main() {
	Student s = Student();
	system("pause");//;作用域在main函数内,pause暂停,未出作用域
}

再来看下面这个类:

class Teacher {
public:
	int* age;
	Teacher() {
		age = new int(0);//堆区,需要手动删除
		cout << "Teacher()" << endl;
	}
	~Teacher() {
		//delete age;
		cout << "~Teacher()" << endl;
	}
};
int* test2() {
	Teacher t = Teacher();
	return t.age;
}

如果main函数如下,虽然析构了,但是没有删干净:

void main() {
	int* age = test2();
	cout << *age << endl;//所以这里依然访问的到
}

这里new应该跟delete配对。

四、浅拷贝/深拷贝(重点)

class Teacher {
public:
	int* age;
	Teacher() //默认构造函数
	{
		age = new int(0);
		cout << "Teacher()" << endl;
	}
	~Teacher() {
		delete age;
		cout << "~Teacher()" << endl;
	}
};
void test2() {
	Teacher t1;
	Teacher t2(t1);//浅拷贝
	cout << *t1.age << endl;
	cout << *t2.age << endl;//delete了两次,出错
}

深拷贝就能解决上面的问题,只是会多占一份内存。
深拷贝只需要在上面的代码基础上加一个拷贝构造函数,函数如下:

Teacher(const Teacher& t) //深拷贝
{
	age = new int(*t.age);
	cout << "Teacher(const Teacher & s)" << endl;
}

五、类的初始化

class Student {
public:
	int id;
	Student() : id(0) {}//默认
	Student(int _id) : id(_id) {}//传参
	Student(const Student& s) : id(s.id) {}//拷贝
};

六、类的成员是另一个类(小重点)

class Teacher1 {
public:
	Student s;
};
void main() {
	Student s;
	Teacher1 t1(s);
}

构造时先构造里面的类(Student),再构造外面的类(Teacher1),析构时先析构外面的类,再析构里面的类。

七、this指针

class Student {
public:
	int id;
	Student(int id) {
		this->id = id;
		//id=id;//会报错
	}
	Student(const Student& s) //拷贝构造函数
	{
		id = s.id;
		cout << "Student(const Student& s)" << endl;
	}
	Student& id_plus1(Student& s) {
		id += s.id;
		return *this;
	}
	Student* id_plus2(Student& s) {
		id += s.id;
		return this;
	}
	Student id_plus3(Student& s) //不考,只考前两个链式调用
	{
		id += s.id;
		return *this;
	}
};
void main() {
	Student s1(18);
	cout << s1.id << endl;//18
	Student s2(18);
	s2.id_plus1(s1).id_plus1(s1);//54,链式调用
	//s2.id_plus2(s1)->id_plus2(s1);//54,链式调用
	//s2.id_plus3(s1).id_plus3(s1);//调用拷贝构造函数,s2其实只加了一次,所以输出36
	cout << s2.id << endl;
}

八、const关键字(不重点考察)

函数加const不能修改属性的值,但是加个mutable又可以修改(控制权限)。

class Student {
public:
	int id;//不能修改
	mutable int age;//可以修改
void modify1() const {
	id = 100;
	age = 18;
	}
};
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值