当前位置: 首页 > news >正文

C++ 第二阶段:类与对象 - 第三节:成员函数与访问权限

目录

一、成员函数

1.1 成员函数的概念

1.2 成员函数的定义

1.2.1 类内定义(内联函数)

1.2.2 类外定义

1.3 成员函数的调用

输出结果

二、访问权限控制

2.1 访问修饰符的作用

2.2 访问权限的控制规则

2.3 示例代码

三、内联函数(Inline Functions)

3.1 内联函数的概念

3.2 显式内联函数

输出结果

四、友元(Friend)

4.1 友元函数

输出结果

4.2 友元类

五、封装性与访问权限设计

5.1 封装性原则

5.2 示例代码

输出结果

六、访问权限在继承中的行为

6.1 继承中的访问权限

6.2 示例代码

七、常见错误与注意事项

7.1 访问权限错误

7.2 友元关系错误

八、总结

8.1 核心要点

8.2 设计原则


C++从入门到入土学习导航_c++学习进程-CSDN博客

一、成员函数

1.1 成员函数的概念

  • 成员函数member function)是类中定义的函数,用于操作类的数据成员或实现类的行为。
  • 特点
    • 可以直接访问类的所有数据成员(包括 private 和 public)。
    • 支持在类内定义(内联函数)或类外定义。
    • 可以被对象调用(通过 . 或 -> 操作符)。

1.2 成员函数的定义

1.2.1 类内定义(内联函数)
  • 语法
    class ClassName {
    public:void memberFunction() {// 函数体}
    };
  • 特点
    • 自动被视为内联函数(inline),减少函数调用的开销。
    • 适用于简单逻辑的函数。
1.2.2 类外定义
  • 语法
    class ClassName {
    public:void memberFunction(); // 声明
    };// 定义
    void ClassName::memberFunction() {// 函数体
    }
  • 特点
    • 需要显式使用作用域解析运算符 ::
    • 如果需要内联,需显式添加 inline 关键字。

1.3 成员函数的调用

  • 语法

    ClassName obj;
    obj.memberFunction(); // 通过对象调用
  • 示例

    #include <iostream>
    using namespace std;class Rectangle {
    private:int width, height;
    public:void setDimensions(int w, int h) {width = w;height = h;}int area() {return width * height;}
    };int main() {Rectangle rect;rect.setDimensions(5, 10);cout << "Area: " << rect.area() << endl;return 0;
    }
输出结果
Area: 50

二、访问权限控制

2.1 访问修饰符的作用

  • public:成员可在类内部、外部和派生类中访问。
  • private:成员只能在类内部访问。
  • protected:成员可在类内部和派生类中访问,但不能在类外部直接访问。

2.2 访问权限的控制规则

访问修饰符类内部类外部派生类
public
private
protected

2.3 示例代码

#include <iostream>
using namespace std;class MyClass {
private:int privateData;
protected:int protectedData;
public:int publicData;void accessAll() {privateData = 1;       // ✅ 允许访问protectedData = 2;     // ✅ 允许访问publicData = 3;        // ✅ 允许访问}
};int main() {MyClass obj;obj.publicData = 10;       // ✅ 允许访问// obj.protectedData = 20; // ❌ 错误:protected 成员不可访问// obj.privateData = 30;   // ❌ 错误:private 成员不可访问return 0;
}

三、内联函数(Inline Functions)

3.1 内联函数的概念

  • 内联函数是编译器优化的一种方式,通过将函数体直接嵌入调用点来减少函数调用的开销。
  • 特点
    • 适用于短小、频繁调用的函数。
    • 类内定义的成员函数默认为内联函数。

3.2 显式内联函数

  • 语法

    inline void myFunction() {// 函数体
    }
  • 示例

    #include <iostream>
    using namespace std;class MathUtils {
    public:inline int add(int a, int b) {return a + b;}
    };int main() {MathUtils mu;cout << "Sum: " << mu.add(5, 7) << endl;return 0;
    }
输出结果
Sum: 12

四、友元(Friend)

4.1 友元函数

  • 用途:允许非成员函数访问类的 privateprotected 成员。

  • 语法

    class MyClass {friend void friendFunction(MyClass& obj);
    private:int secret;
    };
  • 示例

    #include <iostream>
    using namespace std;class MyClass {friend void displaySecret(MyClass& obj); // 声明友元函数
    private:int secret = 42;
    };void displaySecret(MyClass& obj) {cout << "Secret: " << obj.secret << endl; // ✅ 允许访问
    }int main() {MyClass obj;displaySecret(obj);return 0;
    }
输出结果
Secret: 42

4.2 友元类

  • 用途:允许一个类访问另一个类的 private 或 protected 成员。
  • 语法
    class FriendClass {void accessPrivate();
    };class MyClass {friend class FriendClass; // 声明友元类
    private:int secret = 42;
    };void FriendClass::accessPrivate() {MyClass obj;cout << "Secret: " << obj.secret << endl; // ✅ 允许访问
    }

五、封装性与访问权限设计

5.1 封装性原则

  • 数据隐藏:将数据成员声明为 private,通过 public 的 getter 和 setter 方法访问。
  • 接口设计:将对外提供的功能声明为 public,内部实现细节隐藏为 private

5.2 示例代码

#include <iostream>
using namespace std;class BankAccount {
private:double balance;
public:BankAccount(double initialBalance) : balance(initialBalance) {}// 设置余额(验证输入)void setBalance(double amount) {if (amount >= 0) {balance = amount;} else {cout << "Invalid amount!" << endl;}}// 获取余额double getBalance() const {return balance;}// 存款void deposit(double amount) {if (amount > 0) {balance += amount;} else {cout << "Invalid deposit amount!" << endl;}}// 取款void withdraw(double amount) {if (amount > 0 && amount <= balance) {balance -= amount;} else {cout << "Invalid withdrawal amount!" << endl;}}
};int main() {BankAccount account(1000);account.deposit(500);account.withdraw(200);cout << "Final Balance: " << account.getBalance() << endl;return 0;
}
输出结果
Final Balance: 1300

六、访问权限在继承中的行为

6.1 继承中的访问权限

  • public 继承:基类的 public 成员在派生类中仍为 publicprotected 成员变为 protected
  • protected 继承:基类的 public 和 protected 成员在派生类中均为 protected
  • private 继承:基类的 public 和 protected 成员在派生类中均为 private

6.2 示例代码

#include <iostream>
using namespace std;class Base {
public:void publicFunc() { cout << "Base::publicFunc" << endl; }
protected:void protectedFunc() { cout << "Base::protectedFunc" << endl; }
private:void privateFunc() { cout << "Base::privateFunc" << endl; }
};// public 继承
class DerivedPublic : public Base {
public:void access() {publicFunc();       // ✅ 允许访问protectedFunc();    // ✅ 允许访问// privateFunc();   // ❌ 错误:private 成员不可访问}
};// private 继承
class DerivedPrivate : private Base {
public:void access() {publicFunc();       // ✅ 允许访问(在派生类中变为 private)protectedFunc();    // ✅ 允许访问(在派生类中变为 private)// privateFunc();   // ❌ 错误:private 成员不可访问}
};

七、常见错误与注意事项

7.1 访问权限错误

  • 错误示例
    class MyClass {
    private:int secret;
    };int main() {MyClass obj;obj.secret = 10; // ❌ 错误:secret 是 private 成员return 0;
    }

7.2 友元关系错误

  • 错误示例
    class A {friend class B; // A 允许 B 访问其私有成员
    };class B {friend class C; // C 无法直接访问 A 的私有成员
    };class C {void accessA(A& a) {// a.secret = 10; // ❌ 错误:C 无法访问 A 的私有成员}
    };

八、总结

8.1 核心要点

  • 成员函数是类的核心,用于定义类的行为。
  • 访问权限public/private/protected)控制成员的可访问范围。
  • 内联函数可以提高性能,适用于简单逻辑。
  • 友元机制允许非成员函数或类访问私有成员,但需谨慎使用。
  • 封装性是面向对象设计的核心,应将数据成员设为 private,通过 public 接口操作。

8.2 设计原则

  • 最小化暴露:仅将必要的成员声明为 public
  • 优先使用 class:默认访问权限为 private,更符合面向对象设计。
  • 合理使用友元:避免过度依赖,破坏封装性。
http://www.lryc.cn/news/573759.html

相关文章:

  • 理解贝叶斯分析中的“模型比较”部分
  • 【ISP】WDR and HDR
  • Netty ChannelPipeline和ChannelHandler详解
  • 61-Oracle SQL Monitor-实操
  • 多源异构数据接入与实时分析:衡石科技的技术突破
  • RabbitMQ从入门到实践:消息队列核心原理与典型应用场景
  • Java基础 6.22
  • 开源 python 应用 开发(一)python、pip、pyAutogui、python opencv安装
  • 通达信【千军趋势决策系统】幅图指标
  • idea2023+zulu-jdk+maven3.9.10
  • 创建 Vue 3.0 项目的两种方法对比:npm init vue@latest vs npm init vite@latest
  • 新冠疫情分布动态展示图
  • 多设备Obsidian笔记同步:WebDAV与内网穿透技术高效实现教程
  • Javaweb - 3 CSS
  • 没掌握的知识点记录
  • 基于全志T133-s3 busybox 设置登录用户名及密码
  • 【队列】-----【简单的数据结构】
  • leetcode:面试题 08.06. 汉诺塔问题
  • 【unitrix】 4.1 类型级加一操作(Add1.rs)
  • 大模型应用:如何使用Langchain+Qwen部署一套Rag检索系统
  • 【教程】不同架构(armv7l等)下载Miniconda安装包
  • RA4M2开发IOT(11)----ADC检测电压
  • 如何用AI开发完整的小程序<10>—总结
  • webRTC源码配置和编译 + Vscode Intelligence配置
  • 9大策略深度解析MySQL多表JOIN性能优化
  • Python-break、continue与else语句
  • 实战记录:minapp框架下跨机型接口调用顺序引发的兼容性问题
  • 如何仅用AI开发完整的小程序<6>—让AI对视觉效果进行升级
  • AAudio:Android 低延迟音频处理的核心组件
  • WEB3开启 Hardhat 自动验证有什么意义