当前位置:首页 » 《关注互联网》 » 正文

c++的类和对象(1)

16 人参与  2024年12月10日 18:01  分类 : 《关注互联网》  评论

点击全文阅读


1.类的引入

类的引入是面向对象编程(OOP)中的一个基本概念,它代表了面向对象编程范式的核心。在C++中,类(Class)是一种用户定义的数据类型,它将数据表示(属性)和操作数据的方法(函数)组合成一个单一的实体。 

class ClassName {    // 类的成员变量(属性)    // 类的成员函数(方法)public:    // 公有成员(可以被类外部访问)protected:    // 保护成员(可以被类自身、派生类以及友元函数访问)private:    // 私有成员(只能被类自身访问)};

 

类的引入目的

模块化:类允许程序员将复杂的系统分解成更小、更易于管理的模块。代码复用:通过继承机制,类可以继承其他类的特性,减少代码重复。易于维护:由于类封装了数据和操作,因此更改类的内部实现不会影响到其他部分的代码。增强安全性:通过访问控制,类可以保护其数据不被不恰当的访问和修改。


2.类的定义

类定义的组成部分

访问修饰符

public:公有成员可以被类的外部访问。protected:保护成员可以被类自身、派生类以及友元函数访问。private:私有成员只能被类自身访问。

成员变量:类中定义的数据。

成员函数:类中定义的操作数据的函数。

构造函数:用于初始化类的对象。

析构函数:用于在对象生命周期结束时执行清理工作。

类定义的示例

#include <string>class Person {private:    // 私有成员变量    std::string name;    int age;public:    // 构造函数    Person(std::string n, int a) : name(n), age(a) {}    // 成员函数,设置姓名    void setName(std::string n) {        name = n;    }    // 成员函数,获取姓名    std::string getName() const {        return name;    }    // 成员函数,设置年龄    void setAge(int a) {        age = a;    }    // 成员函数,获取年龄    int getAge() const {        return age;    }    // 成员函数,显示个人信息    void display() const {        std::cout << "Name: " << name << ", Age: " << age << std::endl;    }};


3.类的封装

封装

封装是一种将数据和操作数据的函数捆绑在一起的方法,以防止外部直接访问类的内部工作细节。封装的目的包括:

隐藏实现细节:用户不需要知道类的内部工作方式,只需要知道如何使用它。保护数据:防止外部直接修改类的内部状态,确保数据的一致性和完整性。模块化:通过封装,类的内部实现可以独立于其他类的实现进行更改,而不会影响使用该类的代码。
class BankAccount {private:    // 私有成员变量,只能被类内部访问    double balance;public:    // 构造函数,初始化账户余额    BankAccount(double initialBalance) : balance(initialBalance) {}    // 公有成员函数,用于存钱    void deposit(double amount) {        if (amount > 0) {            balance += amount;        }    }    // 公有成员函数,用于取钱    bool withdraw(double amount) {        if (amount > 0 && balance >= amount) {            balance -= amount;            return true;        } else {            return false;        }    }    // 公有成员函数,获取账户余额    double getBalance() const {        return balance;    }};int main() {    BankAccount account(1000.0); // 创建账户,初始余额为1000    account.deposit(500.0); // 存入500    account.withdraw(200.0); // 取出200    // 尝试直接访问私有成员变量(错误,编译器将报错)    // account.balance = 0;     std::cout << "Current balance: " << account.getBalance() << std::endl; // 正确地获取余额    return 0;}

4.类的作用域

在C++中,类定义了一个新的作用域,这意味着在类内部声明的名称(如成员变量和成员函数)在类的外部是不可见的,除非通过类的成员访问运算符(.)或者指针/引用的箭头运算符(->)来访问。以下是关于类作用域的一些关键点:

类作用域的特点:

成员变量和成员函数

在类内部声明的成员变量和成员函数属于类的作用域。成员变量和成员函数默认是私有的,除非明确指定为publicprotected

名称隐藏

类内部的名称会隐藏外部的同名名称。如果在类内部声明了一个与外部同名的变量或函数,那么在类的作用域内,这个内部名称会覆盖外部名称。

作用域解析运算符

如果需要在类外部访问类的成员,需要使用作用域解析运算符::

构造函数和析构函数

构造函数和析构函数也属于类的作用域,它们在创建和销毁类的对象时被调用。
class MyClass {public:    int publicVar; // 公有成员变量    void publicFunc() { // 公有成员函数        // 在这里可以访问类的所有成员    }private:    int privateVar; // 私有成员变量    void privateFunc() { // 私有成员函数        // 在这里可以访问类的所有成员    }    // 构造函数    MyClass() {        privateVar = 0;    }};int main() {    MyClass obj;    // 访问公有成员    obj.publicVar = 10; // 正确    obj.publicFunc();   // 正确    // 尝试访问私有成员(错误,编译器将报错)    // obj.privateVar = 20; // 错误    // obj.privateFunc();   // 错误    return 0;}

 

类的对象大小的计算

在C++中,类对象的大小取决于其成员变量的大小、对齐要求以及可能的填充(padding)字节。以下是计算类对象大小的几个关键点:

成员变量:类对象的大小至少是其所有非静态成员变量大小的总和。

成员对齐:每个成员变量可能有其特定的对齐要求。对象的内存布局会按照这些对齐要求来调整。

类对齐:整个类对象可能也有一个对齐要求,这会影响对象的总大小。

填充字节:编译器可能会在成员变量之间插入填充字节以满足对齐要求。

 

class MyClass {    int a;       // 通常占用4字节    char b;      // 占用1字节    double c;    // 通常占用8字节    // 可能的填充字节};// 假设默认对齐数为8// 计算过程:// a占用4字节,b占用1字节,但由于double需要对齐到8字节,所以b之后会有3字节的填充// c占用8字节// 因此,MyClass对象的总大小为:4 + 1 + 3(填充) + 8 = 16字节

类成员函数的this指针

在C++中,每个非静态成员函数都有一个隐含的参数,称为this指针。this指针指向调用该成员函数的对象本身。以下是关于this指针的一些关键点:

隐含参数this指针是隐含传递给成员函数的第一个参数。

类型this指针的类型是类类型的指针,例如MyClass*

用途this指针用于访问调用该函数的对象的成员变量和成员函数。

非静态成员函数:只有非静态成员函数才有this指针。

默认值:在成员函数内部,可以显式地使用this指针,也可以省略它,因为编译器会自动添加。

class MyClass {public:    int value;    void setValue(int val) {        this->value = val; // 使用this指针显式地设置成员变量    }    int getValue() const {        return this->value; // 使用this指针显式地获取成员变量    }};MyClass obj;obj.setValue(10); // 调用时,编译器会隐含传递this指针int val = obj.getValue(); // 同样,编译器会隐含传递this指针


点击全文阅读


本文链接:http://zhangshiyu.com/post/199240.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1