一、封装
1、封装的意义
将属性和行为作为一个整体,表现生活中的事物将属性和行为加以权限控制
#include <iostream> using namespace std; //圆周率 const double PI = 3.14; //设计圆类,求圆的周长 2*PI*半径 class Circular { public: // 半径 int m_r; // 周长 double calculateGirth() { return 2 * PI * m_r; } }; int main() { // 实例化一个圆 Circular c1; c1.m_r = 10; cout << c1.calculateGirth() << endl; return 0; }
62.8
#include <iostream> using namespace std; //学生 class Student { public: string name; int no; const string &getName() const { return name; } void setName(const string &name) { Student::name = name; } int getNo() const { return no; } void setNo(int no) { Student::no = no; } void showInfo() { cout << "姓名:" << name << "学号:" << no << endl; } }; int main() { // 实例化 Student stu; stu.name = "zhangsan"; stu.no = 13131321; stu.showInfo(); return 0; }
姓名:zhangsan学号:13131321
三种访问权限
public 成员 类内可以访问 类外可以访问
protected 成员 类内可以访问 类外不可以访问 子类可以访问
private 成员 类内可以访问 类外不可以访问 子类不能访问
#include <iostream> using namespace std; //三种访问权限 //public 成员 类内可以访问 类外可以访问 //protected 成员 类内可以访问 类外不可以访问 子类可以访问 //private 成员 类内可以访问 类外不可以访问 子类不能访问 class Person { // 共有权限 public: string m_Name;//姓名 //保护权限 protected: string m_Car;//汽车 //私有权限 private: // 私有权限 int m_password;//银行卡密码 public: void func() { m_Name = "zhangsan"; m_Car = "xiaopeng"; m_password = 123456; } }; int main() { //实例化具体对象 Person p1; p1.m_Name = "lishi"; return 0; }
2、struct和class区别
struct 默认权限为公共 class 默认权限为私有
#include <iostream> using namespace std; class C1 { int m_A; //默认私有 private }; struct C2 { int m_A; //默认公共 public }; int main() { // class与struct区别 C1 c1; // c1.m_A = 12; 无法访问 私有 C2 c2; c2.m_A = 13; return 0; }
3、成员属性设置为私有
优点1:将所有成员属性设置为私有,可以自己控制读写权限; 优点2:对于写权限,我们可以检测数据的有效性。
#include <iostream> using namespace std; class Person { public: // 设置姓名 void setName(string name) { m_Name = name; } // 获取姓名 string getName() { return m_Name; } //设置年龄,检查有效性 void setAge(int age) { if (age > 100 || age < 0) { cout << "只能设置0-100之间的数字" << endl; return; } m_Age = age; } private: string m_Name; int m_Age; }; int main() { Person p; p.setName("zhangsan"); cout << p.getName() << endl; p.setAge(0); return 0; }
设计立方体类(Cube)
求出立方体的面积和体积
分别用全局函数和成员函数判断两个立方体是否相等。
#include <iostream> using namespace std; class Cube { public : // 设置获取长 void setL(int l) { m_L = l; } int getL() { return m_L; } // 设置获取宽 void setW(int w) { m_W = w; } int getW() { return m_W; } // 设置获取高 void setH(int h) { m_H = h; } int getH() { return m_H; } //获取体积 int calculateS() { return 2 * m_L * m_W + 2 * m_W * m_H + 2 * m_H * m_L; } //获取面积 int calculateV() { return m_L * m_H * m_W; } //成员函数判断 bool isSameByclass(Cube &c) { if (getL() == c.getL() && getH() == c.getH() && getW() == c.getW()) { return true; } return false; } private: int m_L;//长 int m_W;//宽 int m_H;//高 }; //全局函数,判断立方体是否相等 bool isSame(Cube &c1, Cube &c2) { if (c1.getL() == c2.getL() && c1.getH() == c2.getH() && c1.getW() == c2.getW()) { return true; } return false; } int main() { Cube c1; c1.setH(10); c1.setW(10); c1.setL(10); cout << "立方体的面积:" << c1.calculateS() << endl; cout << "立方体的体积:" << c1.calculateV() << endl; Cube c2; c2.setH(10); c2.setW(10); c2.setL(20); cout << isSame(c1, c2) << endl; cout << c1.isSameByclass(c2) << endl; return 0; }
立方体的面积:600 立方体的体积:1000 0 0
设计一个圆形类 (Circle) ,和一个点类 (Point) ,计算点和圆的关系。
#include <iostream> #include "Point.h" #include "Circle.h" using namespace std; //判断圆和点的关系 void isInCircle(Circle &c, Point &p) { int pX = p.getX(); int pY = p.getY(); int cX = c.getCenter().getX(); int cY = c.getCenter().getY(); int ret = (pX - cX) * (pX - cX) + (pY - cY) * (pY - cY) - c.getR() * c.getR(); if (ret == 0) { cout << "点在圆上" << endl; } else if (ret < 0) { cout << "点在圆内" << endl; } else { cout << "点在圆外" << endl; } } int main() { Point p; p.setX(0); p.setY(0); Circle c; c.setCenter(p); c.setR(10); Point p1; p1.setX(10); p1.setY(0); Point p2; p2.setX(-11); p2.setY(0); isInCircle(c, p); isInCircle(c, p1); isInCircle(c, p2); return 0; }
Point.h
#pragma once //防止头文件重复包含 #include <iostream> using namespace std; //点类 class Point { public : void setX(int x); int getX(); void setY(int y); int getY(); private: int m_X; int m_Y; };
Point.cpp
#include "Point.h" void Point::setX(int x) { m_X = x; } int Point::getX() { return m_X; } void Point::setY(int y) { m_Y = y; } int Point::getY() { return m_Y; }
Circle.h
#pragma once //防止头文件重复包含 #include <iostream> #include "Point.h" using namespace std; //圆类 class Circle { public: void setR(int r); int getR(); void setCenter(Point point); Point getCenter(); private: int m_R;//半径 Point m_Center;//圆心 };
Circle.cpp
#include "Circle.h" //圆类 void Circle::setR(int r) { m_R = r; } int Circle::getR() { return m_R; } void Circle::setCenter(Point point) { m_Center = point; } Point Circle::getCenter() { return m_Center; }
程序运行结果
点在圆内 点在圆上 点在圆外
二、对象的初始化和清理
1、构造函数和析构函数
#include <iostream> using namespace std; //对象的初始化和清理 //1、构造函数 进行初始化操作 class Person { public: /** * 构造函数没有返回值,不用写void * 函数名与类名相同 * 构造函数可以后参数,可以发生重载 * 创建对象的时候,构造函数会自动调用,而且只调用一次 */ Person() { cout << "Person 无参构造函数调用了" << endl; } //2、析构函数进行清理的操作 /** * 没有返回值 不写void * 函数名与类名相同 在名称前加~ * 析构函数不可以有参数,不可以发生重载 * 对象在销毁前,会自动调用析构函数,只调用一次 */ ~Person() { cout << "Person 析构函数调用了" << endl; } }; int main() { Person p1; return 0; }
Person 无参构造函数调用了 Person 析构函数调用了
2、构造函数的分类和调用
#include <iostream> using namespace std; //对象的初始化和清理 class Person { public: // 构造函数 按照参数分类 有参和无参 Person() { cout << "Person 无参构造函数调用了" << endl; } Person(int a) { age = a; cout << "Person 有参构造函数调用了" << endl; } //按照类型分类 普遍构造函数和拷贝构造函数 //拷贝构造函数 Person(const Person &person) { cout << "Person 拷贝构造函数调用了" << endl; age = person.age; } //析构函数 ~Person() { cout << "Person 析构函数调用了" << endl; } public: int age; }; //调用 void test() { // 1、括号法 Person p1; //默认、无参,调用默认参数不使用(); Person p1();会被认为是函数p1的申明; Person p2(10);//有参 Person p3(p2);//拷贝 cout << p2.age << endl; cout << p3.age << endl; //2、显示法 Person p21; Person p22 = Person(10); //有参构造 Person p23 = Person(p22); //拷贝构造 //Person(10);匿名对象,当前行执行后,系统会立即回收掉匿名对象; //Person(p3); 不用利用拷贝对象初始化匿名对象 编译器会认为Person(p3)===Person p3; //3、隐式转换法 Person p4 = 20;//Person p4=Person(20); Person p5 = p4;//Person p5=Person(p4); } int main() { test(); return 0; }
Person 无参构造函数调用了 Person 有参构造函数调用了 Person 拷贝构造函数调用了 10 10 Person 无参构造函数调用了 Person 有参构造函数调用了 Person 拷贝构造函数调用了 Person 有参构造函数调用了 Person 拷贝构造函数调用了 Person 析构函数调用了 Person 析构函数调用了 Person 析构函数调用了 Person 析构函数调用了 Person 析构函数调用了 Person 析构函数调用了 Person 析构函数调用了 Person 析构函数调用了
3、拷贝构造函数调用时机
使用一个已经创建完毕的对象来初始化一个新对象 值传递的方式给函数参数传值 以值的方式返回局部对象
#include <iostream> using namespace std; //拷贝构造函数调用时机 class Person { public: Person() { cout << "Person默认构造函数调用" << endl; } Person(int a) { m_Age = a; cout << "Person有参构造函数" << endl; } Person(const Person &p) { m_Age = p.m_Age; cout << "Person拷贝构造函数" << endl; } ~Person() { cout << "Person析构函数调用" << endl; } int m_Age; }; //1、使用一个已经创建完毕的对象来初始化一个新对象(最常用) void test01() { Person p1(10); Person p2(p1); } //2、值传递的方式给函数参数传值 void doWork(Person p) { } //值传递,会拷贝一个临时副本 void test02() { Person p; doWork(p); } //3、值方式返回局部对象 Person doWork2() { Person p1; cout << &p1 << endl; return p1; } void test03() { Person p = doWork2(); cout << &p << endl; } int main() { // test01(); // test02(); test03(); return 0; }
Person默认构造函数调用 0x66fd0c 0x66fd0c Person析构函数调用