零基础学C++—— 类和对象(1) (超详细!!!)

1.类和对象的基本概念

1、现实世界的事物所具有的共性就是每个事物都具有自身的属性,一些自身具有的行为,例如一 个具学生有姓名、性别、年龄等属性,吃饭睡觉玩游戏等行为。
C++提供了类的概念,可以将某一类事物的所有属性和行为封装在一个class中。
2、类对于某个事物的描述其实还是抽象的,例如有一类事物有姓名、性别、年龄等属性,可以吃饭睡觉玩游戏等行为,如果只是这么描述的话其实我们是不知道这个事物具体是什么样的,因为这个类没有告诉我们每个属性具体的值是多少(这个事物的姓名是什么,年龄是多少) ,所以类只是对某一类事物的一个描述而已。实际应用中我们需要操作某类事物中一个或者多个具体的事物。那么这个具体的事物我们就称之为对象。
4、对象是怎么来的呢?由类实例化而来。因此我们也说通过一个类实例化一个对象。
3、类是抽象的,对象是具象的。

2.类的定义

一个类里面通常包含以下几个主要组成部分:

  1. 成员变量(Attributes/Properties):
    这些变量用于存储类的状态或数据。成员变量可以是任何数据类型,包括基本数据类型(如int, float, char等)、复合数据类型(如数组、结构体等),甚至是其他类的对象。成员变量可以是公有的(public)、私有的(private)或受保护的(protected),这决定了它们在其他类或对象中的可见性和可访问性。
  2. 成员函数(Methods):
    成员函数定义了可以在类的对象上执行的操作。这些函数可以执行各种任务,比如修改成员变量的值、执行计算、与其他对象交互等。成员函数同样可以有不同的访问修饰符,控制其在类外部的可见性。
  3. 还有构造函数,析构函数,静态成员,友元函数和友元类,类型别名和嵌套类型,常量、枚举和静态断言等等,这里暂时不讲。
    以下是一个简单的C++类的例子,它定义了一个名为Rectangle的矩形类:
#include<iostream>
using namespace std;

// 长方体类定义
class Cuboid {
private: // 私有成员
    double length; // 长 这里定义了三个double类型的成员变量
    double width;  // 宽
    double height; // 高

public: // 公有成员
    // 构造函数,用于初始化长方体的长、宽和高
    Cuboid(double len, double wid, double hig) {
        length = len;
        width = wid;
        height = hig;
    }
    //无参数构造函数
    Cuboid() {
    length = 2.0;
    width = 3.0;
    height = 4.0;
    }

    // 成员函数:设置长方体的长
    void setLength(double len) {
        length = len;
    }

    // 成员函数:设置长方体的宽
    void setWidth(double wid) {
        width = wid;
    }

    // 成员函数:设置长方体的高
    void setHeight(double hig) {
        height = hig;
    }

    // 成员函数:获取长方体的长
    double getLength() const {
        return length;
    }

    // 成员函数:获取长方体的宽
    double getWidth() const {
        return width;
    }

    // 成员函数:获取长方体的高
    double getHeight() const {
        return height;
    }

    // 成员函数:计算长方体的表面积
    double surfaceArea() const {
        return 2 * (length * width + width * height + height * length);
    }

    // 成员函数:计算长方体的体积
    double volume() const {
        return length * width * height;
    }

    // 成员函数:输出长方体的信息
    void print() const {
        cout << "长: " << length << "  宽: " << width << "  高: " << height << endl;
        cout<<"表面积: " << surfaceArea()<< " 体积: " << volume() << endl;
    }
};

int main() {
    // 创建一个Cuboid对象并设置长方体的长、宽和高
    Cuboid cuboid(4.0, 5.0, 6.0);//自动调用带3个参数的构造函数
    //Cuboid cuboid;//自动调用无参数构造函数
    // 调用对象的print成员函数显示信息
    cuboid.print();

    return 0;
}

3.代码解释

类的访问权限:

类的成员有三种访问权限:public、private和protected,分别表示公有的、私有的和受保护的。
在类的内部(类的成员函数中),无论成员被声明为 public还是private,都可以访问。
在类的外部(定义类的代码之外),只能访问public成员,不能访问 private、protected成员。
在一个类体的定义中,private 和 public 可以出现多次。
结构体的成员缺省为public,类的成员缺省为private。也就是说如果没有写明是public还是private,那在结构体里面默认就是public,在类里面默认是private
private的意义在于隐藏类的数据和实现,把需要向外暴露的成员声明为public。

那C++里为什么要有访问限制符呢?
想象一下,你有一个宝贵的宝箱,里面装满了珍贵的物品。这个宝箱就相当于一个C++中的类,而里面的珍贵物品就是类的数据成员。你肯定不希望任何人都能随便打开这个宝箱,乱拿里面的东西,对吧?
这时候,访问限制符就像是为宝箱加上的几把锁。private锁是最严密的,它确保只有你自己(也就是类内部的代码)才能打开宝箱,取出或放入物品。其他人(类外部的代码)都无法直接访问。
public锁则相反,它相当于把宝箱完全敞开,任何人都可以自由地查看、取出或放入物品。这通常用于那些你希望与其他人共享的物品,或者是宝箱的外部装饰(比如类的公共接口)。
而protected锁则介于两者之间。它允许你的亲朋好友(派生类)在特定情况下打开宝箱,但对外人仍然是封闭的。这样,你可以在保证安全性的同时,又与亲近的人分享一些私密。
总的来说,访问限制符就像是你为宝箱加上的不同级别的锁,帮助你控制谁可以访问宝箱里的内容,从而保护你的珍贵物品不被随意破坏或窃取。在C++编程中,这些“锁”就是用来保护你的数据和代码,确保它们按照你的意愿被安全、有序地访问和使用。
上面的代码里将长宽高设置为private就是不想让别人随意修改。

构造函数

构造函数是C++中的一种特殊成员函数,它在对象创建时自动调用,用于初始化对象的数据成员。构造函数与类同名,没有返回类型,可以重载(即同一个类可以有多个构造函数,参数列表不同)。通过构造函数,可以确保对象在被使用时已处于有效状态。
注意:以下方法不会调用无参构造函数
Cuboid a(): //不是构造对象,而是代表声明一个函数!!

构造函数的特点:

  1. 函数名与类名相同:
class MyClass {
public:
    MyClass() { // 构造函数名称与类名相同
        // 初始化代码
    }
};
  1. 无返回值:
class MyClass {
public:
    MyClass() { // 构造函数没有返回类型,甚至连void也没有
        // 初始化代码
    }
};
  1. 可带有参数:
class MyClass {
public:
    MyClass(int x, double y) { // 构造函数带有两个参数
        // 使用x和y进行初始化
    }
};
  1. 可以设置默认值:
class MyClass {
public:
    MyClass(int x = 0, double y = 0.0) { // 构造函数参数带有默认值
        // 使用x和y进行初始化,如果创建对象时没有提供参数,则使用默认值
    }
};
  1. 可被重载:
class MyClass {
public:
    MyClass() { // 无参构造函数
        // 初始化代码
    }
    MyClass(int x) { // 带有一个参数的构造函数,重载了上面的无参构造函数
        // 使用x进行初始化
    }
    MyClass(int x, double y) { // 带有两个参数的构造函数,进一步重载
        // 使用x和y进行初始化
    }
};
  1. 自动调用:
class MyClass {
public:
    MyClass() {
        std::cout << "自动调用了!" << std::endl;
    }
};

int main() {
    MyClass obj; // 创建对象时自动调用构造函数
    return 0;
}
  1. 私有构造函数(通常与友元类或函数一起使用和继承性(子类构造函数会调用父类构造函数),这里暂时不讲。
  2. 注意:如果在类中实现了带参数的构造函数,一般要实现一个无参的构造函数,因为如果在构造对象时不带参数将无法找到无参的构造函数导致编译失败。
  3. 注意:类是定义对象结构和行为的模板,不直接占用内存;而对象是类的实例,会在程序运行时占用具体的内存空间。
普通成员函数

这里的普通成员函数指的是像setLength()类的设置函数(setter),getLength()类的获取函数(getter)还有一些像surfaceArea()实现一些功能的函数。那为什么需要像这样的函数呢?以下原因不需要记,理解就好。

  1. 数据封装和隐藏:
  • 通过将数据成员设置为私有(private)或受保护的(protected),类可以确保外部代码不能直接访问或修改这些数据。这样做可以防止数据被意外修改,从而保持数据的完整性和安全性。
  • Setter 和 getter 函数提供了对这些私有数据的间接访问。它们允许类对数据进行必要的验证或转换,然后再设置或返回数据。
class MyClass {
private:
    int secretValue; // 私有数据成员,外部不可直接访问
   
public:
    void setSecretValue(int value) {
        secretValue = value; // 通过公共方法设置私有数据
    }
    int getSecretValue()  {
        return secretValue; // 通过公共方法获取私有数据
    }
};
  1. 数据验证:
  • Setter 函数可以在设置数据值之前执行验证逻辑。例如,如果某个数据成员应该是正数,setter 函数可以检查传入的值是否为正,并在不是的情况下拒绝设置或进行适当的处理。
#include <iostream>

class MyClass {
private:
    int age;
public:
    void setAge(int newAge) {
        if (newAge >= 0 && newAge <= 100) {
            age = newAge; // 如果年龄有效,则设置年龄
        } else {
            std::cout << "Invalid age. Age must be between 0 and 100." << std::endl;
            // 如果年龄无效,则打印错误消息,而不是设置年龄
        }
    }
};

int main() {
    MyClass person;
    person.setAge(120); // 尝试设置一个无效的年龄
    return 0;
}
  1. 未来兼容性:
  • 如果将来需要更改类的内部实现(例如,更改数据成员的存储方式或添加额外的逻辑),使用 setter 和 getter 函数可以更容易地进行这些更改,而无需修改使用该类的外部代码。
// 初始版本
class Rectangle {
public:
    int width, height;
};

// 修改后的版本,保持外部兼容性
class Rectangle {
private:
    int width, height;
public:
    void setWidth(int w) {
        width = w;
        std::cout << "Width set to " << w << std::endl; // 新增逻辑
    }
    void setHeight(int h) {
        height = h;
        std::cout << "Height set to " << h << std::endl; // 新增逻辑
    }
};

如果有疑问,欢迎在评论区提出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值