C++ 教程 - 04 类的使用

发布于:2024-06-28 ⋅ 阅读:(38) ⋅ 点赞:(0)

类的定义

C++ 在 C 语言的基础上增加面向对象编程,类是用于指定对象的形式,是一种用户自定义的数据类型,封装了数据和函数。类可以被看作是一种模板,可以用来创建具有相同属性和行为的多个对象。

  • class 关键字定义类,相当于在结构体中加入方法;
  • 花括号内定义成员变量、成员方法,并且分块表示,每块使用public/private/protected关键字修饰
  • 最后以分号结束
  • 访问修饰符
    • public,公有访问,最大的访问权限,对象可以直接调用属性、方法;
    • protected,受保护的访问,只能在类内部访问(或友元函数),对象无法直接调用;可以被子类继承,并在子类内部访问;
    • private, 私有访问,只能在类内部访问(或友元函数),对象无法直接调用;可以被子类继承,但子类内部也无法访问
  • 使用冒号表示继承;
    • class Dog : public Animal { }; 公有继承,访问权限不变,基类的public、protected、private仍保持不变;
    • class Dog : protected Animal { }; 受保护的继承,基类的public、protected、private变为protected、protected、private
    • class Dog : private Animal { }; 私有继承,继承下来的全部为私有访问权限,基类的public、protected、private变为private、private、private

在这里插入图片描述
 

类定义案例

#include <iostream>
#include <string>
#include <math.h>
using namespace std;


// 类的声明 一般在头文件
class Stu {

public: // 公有权限 接口
	const string& getName() const { // const 表示常量成员函数 (只读,不会改变实例对象的任何数据)
		return name; // this指针指向当前实例对象,可以省略   this->name;
		// 返回name的常量引用,避免值拷贝的内存消耗
	}

	void setName(const string& name) {
		// 直接访问当前对象 的属性
		this->name = name;
	}

private: // 数据放在 私有访问 块
	string name;
};

int main() {

	// 创建对象
	Stu stu;
	// 设置名字
	stu.setName("jack");
	string name = stu.getName();
	cout << "got name:" << name << endl;
	return 0;
}

 

构造函数

  • 与类名相同,无返回值;
  • 创建对象时,对其成员变量进行初始化,成员变量必须初始化后才可以使用;
    • this指针初始化
    • 初始化列表来初始化
  • 未定义构造函数时,编译器默认会定义一个无参构造;
  • 定义构造函数时,需从无参构造开始重载(即参数列表不同的同名函数);此时编译器不再默认定义无参构造;
  • 实例化对象
    • B b; 走无参构造
    • B b(a, b); 走有参构造
    • B* ptr = new B; 走无参构造,动态分配内存(堆内存)
    • B* ptr = new B(a, b); 走有参构造,动态分配内存注意 delete ptr 释放
#include <iostream>
#include <string>
#include <math.h>
using namespace std;


// 类的声明 一般在头文件
class Stu {

public: // 公有权限 接口
	Stu() { // 无参构造函数,无返回值
		cout << "创建对象时,初始化对象" << endl;
	};

	// 重载构造函数(参数列表不同)
	Stu(const string& name) {
		this->name = name; // this指针初始化
	}
	
	// 列表初始化
	Stu(const string& name, const int& age): name(name), age(age){ 
		cout << "列表初始化" << endl;
		// 相当于
		// this->name = name;
		// this->age = age;
	}

	const string& getName() const { // const 表示常量成员函数 (只读,不会改变实例对象的任何数据)
		return name; // this指针指向当前实例对象,可以省略   this->name;
		// 返回name的常量引用,避免值拷贝的内存消耗
	}

	void setName(const string& name) {
		// 直接访问当前对象 的属性
		this->name = name;
	}

private: // 数据放在 私有访问 块
	string name;
};

int main() {

	// 创建对象
	Stu stu("lauf");
	string name = stu.getName();
	cout << "got name:" << name << endl;
	return 0;
}

 

拷贝构造函数

  • 编译器默认会定义拷贝构造函数;
  • 类中有指针变量,且需动态分配内存时,必须定义拷贝构造函数;
  • 同构造函数一样,形参常为类的对象的引用;
  • 使用场景:
    • 使用引用的对象来初始化一个新对象;
    • 函数传参对象(复制对象)、函数返回对象(复制对象);
    • 注意传对象的引用,不会触发拷贝;
       
  • 场景:使用一个已创建的对象初始化一个新对象;
#include <iostream>
#include <string>
#include <math.h>
using namespace std;


// 类的声明 一般在头文件
class Stu {

public: // 公有权限 接口
	Stu() { // 无参构造函数,无返回值
		cout << "创建对象时,初始化对象" << endl;
		this->ptr = new int; // 为指针动态分配内存
		*(this->ptr) = 0;
	};

	// 拷贝 构造函数
	Stu(const Stu& stu) {
		// stu为被拷贝的对象
		cout << "被拷贝的对象:" << *(stu.ptr) << endl;
		*(this->ptr) = *(stu.ptr);
	}

	void setVal(const int& val) {
		*ptr = val;
	}

	void printVal() const {
		cout << *ptr << endl;
	}

private: // 数据封装在私有访问块
	int* ptr; // 包含指针,且需要动态分配内存
};

int main() {

	// 创建对象
	Stu s1;
	s1.setVal(20);

	Stu s2 = s1;  // 使用s1对象初始化 s2, s1是被拷贝的对象,s2为this指向的对象
	s2.printVal();

	return 0;
}

 

  • 场景:函数传参、返回对象,复制对象;
#include <iostream>
using namespace std;


// 类的声明 一般在头文件
class Stu {

public: // 公有权限 接口
	Stu() { // 无参构造函数,无返回值
		cout << "创建对象时,初始化对象" << endl;
		this->ptr = new int; // 为指针动态分配内存
		*(this->ptr) = 0;
	};

	// 拷贝 构造函数
	Stu(const Stu& stu) {
		// stu为被拷贝的对象
		cout << "被拷贝的对象:" << *stu.ptr << endl;
		
		// 拷贝时,会自动创建一个新对象,这里仅为其指针变量分配内存,并初始化
		ptr = new int; // 动态分配内存
		*ptr = *stu.ptr; // 初始化值
	}

	void setVal(const int& val) {
		*ptr = val;
	}

	void printVal() const {
		cout << *ptr << endl;
	}

private: // 数据封装在私有访问块
	int* ptr; // 包含指针,且需要动态分配内存
};


void printObj(Stu stu) { // 值传递,拷贝对象(执行拷贝构造函数)
	stu.printVal();
}

int main() {

	// 创建对象
	Stu s1;
	s1.setVal(20);
	
	printObj(s1);

	return 0;
}

 

析构函数

  • 删除一个对象时,执行的函数,通常用于指针内存释放、文件的关闭等;
  • ~类名,无参、无返回;
#include <iostream>
using namespace std;


// 类的声明 一般在头文件
class Stu {

public: // 公有权限 接口
	Stu() { // 无参构造函数,无返回值
		cout << "创建对象时,初始化对象" << endl;
		this->ptr = new int; // 为指针动态分配内存
		*(this->ptr) = 0;
	};

	// 析构函数,删除对象时,调用
	~Stu() {
		cout << "删除对象时执行" << endl;
		delete ptr; // 释放内存
	}

	void setVal(const int& val) {
		*ptr = val;
	}

	void printVal() const {
		cout << *ptr << endl;
	}

private: 
	int* ptr;
};

int main() {

	// 创建对象
	Stu s1;  // 程序结束,自动删除s1对象
	s1.setVal(20);
	
	return 0;
}

网站公告

今日签到

点亮在社区的每一天
去签到