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

发布于:2025-06-23 ⋅ 阅读:(20) ⋅ 点赞:(0)

目录

一、成员函数

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 设计原则


一、成员函数

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,更符合面向对象设计。
  • 合理使用友元:避免过度依赖,破坏封装性。

网站公告

今日签到

点亮在社区的每一天
去签到