在 C++ 中访问类的私有成员

Jinku Hu 2023年1月30日 2021年4月29日
  1. 在 C++ 中使用 private 访问指定器来封装类成员
  2. 在 C++ 中使用 public 函数来检索类的私有成员
在 C++ 中访问类的私有成员

本文将解释几种如何使用 C++ 访问类的私有成员的方法。

在 C++ 中使用 private 访问指定器来封装类成员

访问说明符用于实现面向对象编程的核心特征-称为封装。结果,我们限制了对类的特定数据成员的直接访问,并从本质上构造了一个对类数据进行操作的接口。C++ 提供了几个访问说明符关键字,例如:publicprivateprotected,它们通常在需要使用相应可访问性进行限定的类成员之前。

private 说明符之后定义的成员只能由成员函数访问,并且不能直接从使用该类的代码中引用。通常,构造类时要考虑两个方面-类的设计者和类的用户。后者通常是受封装影响的那个。如果程序员在第一个访问说明符之前定义成员,则在使用 class 关键字时默认将其可访问性设置为 private,在 struct 关键字上将其访问权限设置为 public

在下面的示例中,我们实现了一个名为 BaseClass 的类,其中有两个声明为私有的字符串数据成员,因此要访问这些成员的值,该类的设计者应包括 public 函数来检索它们。注意,我们可以从下面的代码中删除 public 关键字,并且仍然具有 getUsernamegetName 函数作为 public 成员。

封装的另一个好处是可以灵活地修改内部类的结构,而不必担心用户端的兼容性问题。只要接口(因此公共功能)不变,该类的用户就无需修改其代码。

#include <iostream>
#include <string>
#include <utility>
#include <vector>

using std::cout; using std::endl;
using std::vector; using std::string;

class BaseClass {
public:
    BaseClass() = default;
    explicit BaseClass(string user, string nm):
             username(std::move(user)), name(std::move(nm)) { }

    ~BaseClass() = default;

    string& getUsername() { return username; };
    string& getName() { return name; };

private:
    string username;
    string name;
};

int main()
{
    BaseClass base("buddy", "Buddy Bean");

    cout << "base -> name: " << base.getName() << endl;
    cout << "base -> username: " << base.getUsername() << endl;

    exit(EXIT_SUCCESS);
}

输出:

base -> name: Buddy Bean
base -> username: buddy

在 C++ 中使用 public 函数来检索类的私有成员

可以使用类接口函数来修改 private 成员,例如,changeUsername 函数从类的用户那里获取 string 参数,并将其值存储到 private 成员-username 中。注意,还有一个 friend 关键字,用于区分允许访问该类的 private 成员的其他类和函数。这些函数可以是外部函数,而不是上述类的一部分。请注意,错误使用访问说明符很可能导致编译器错误。

#include <iostream>
#include <string>
#include <utility>
#include <vector>

using std::cout; using std::endl;
using std::vector; using std::string;

class BaseClass {
public:
    BaseClass() = default;
    explicit BaseClass(string user, string nm):
             username(std::move(user)), name(std::move(nm)) { }

    ~BaseClass() = default;

    void changeUsername(const string &s) { username.assign(s); };

    string& getUsername() { return username; };
    string& getName() { return name; };

private:
    string username;
    string name;
};

int main()
{
    BaseClass base("buddy", "Buddy Bean");

    cout << "base -> name: " << base.getName() << endl;
    cout << "base -> username: " << base.getUsername() << endl;
    base.changeUsername("jolly");
    cout << "base -> username: " << base.getUsername() << endl;

    exit(EXIT_SUCCESS);
}

输出:

base -> name: Buddy Bean
base -> username: buddy
base -> username: jolly
Author: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn

相关文章 - C++ Class