在 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