C++类和对象1

简介: C++类和对象

一、封装

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析构函数调用

C++类和对象2:https://developer.aliyun.com/article/1548157

目录
相关文章
|
21小时前
|
数据安全/隐私保护 C++
|
5天前
|
C++
【C++】日期类Date(详解)②
- `-=`通过复用`+=`实现,`Date operator-(int day)`则通过创建副本并调用`-=`。 - 前置`++`和后置`++`同样使用重载,类似地,前置`--`和后置`--`也复用了`+=`和`-=1`。 - 比较运算符重载如`&gt;`, `==`, `&lt;`, `&lt;=`, `!=`,通常只需实现两个,其他可通过复合逻辑得出。 - `Date`减`Date`返回天数,通过迭代较小日期直到与较大日期相等,记录步数和符号。 ``` 这是236个字符的摘要,符合240字符以内的要求,涵盖了日期类中运算符重载的主要实现。
|
15小时前
|
C++
C++基础知识(四:类的学习)
类指的就是对同一类对象,把所有的属性都封装起来,你也可以把类看成一个高级版的结构体。
|
21小时前
|
存储 安全 编译器
|
2天前
|
编译器 C语言 C++
|
2天前
|
编译器 C++
【C++】详解初始化列表,隐式类型转化,类静态成员,友元
【C++】详解初始化列表,隐式类型转化,类静态成员,友元
|
5天前
|
存储 编译器 C++
【C++】类和对象④(再谈构造函数:初始化列表,隐式类型转换,缺省值
C++中的隐式类型转换在变量赋值和函数调用中常见,如`double`转`int`。取引用时,须用`const`以防修改临时变量,如`const int& b = a;`。类可以有隐式单参构造,使`A aa2 = 1;`合法,但`explicit`关键字可阻止这种转换。C++11起,成员变量可设默认值,如`int _b1 = 1;`。博客探讨构造函数、初始化列表及编译器优化,关注更多C++特性。
|
5天前
|
编译器 C++
【C++】类和对象④(类的默认成员函数:取地址及const取地址重载 )
本文探讨了C++中类的成员函数,特别是取地址及const取地址操作符重载,通常无需重载,但展示了如何自定义以适应特定需求。接着讨论了构造函数的重要性,尤其是使用初始化列表来高效地初始化类的成员,包括对象成员、引用和const成员。初始化列表确保在对象创建时正确赋值,并遵循特定的执行顺序。
|
5天前
|
C语言 C++
【C++】日期类Date(详解)③
该文介绍了C++中直接相减法计算两个日期之间差值的方法,包括确定max和min、按年计算天数、日期矫正及计算差值。同时,文章讲解了const成员函数,用于不修改类成员的函数,并给出了`GetMonthDay`和`CheckDate`的const版本。此外,讨论了流插入和流提取的重载,需在类外部定义以符合内置类型输入输出习惯,并介绍了友元机制,允许非成员函数访问类的私有成员。全文旨在深化对运算符重载、const成员和流操作的理解。
|
5天前
|
定位技术 C语言 C++
C++】日期类Date(详解)①
这篇教程讲解了如何使用C++实现一个日期类`Date`,涵盖操作符重载、拷贝构造、赋值运算符及友元函数。类包含年、月、日私有成员,提供合法性检查、获取某月天数、日期加减运算、比较运算符等功能。示例代码包括`GetMonthDay`、`CheckDate`、构造函数、拷贝构造函数、赋值运算符和相关运算符重载的实现。