在 C++ 中使用私有类成员与保护类成员

本文将演示关于如何在 C++ 中正确使用 privateprotected 类成员的多种方法。

在 C++ 中使用 private 属性来表示类的用户无法访问的类成员

private 关键字是 C++ 语言实现封装功能的基本部分之一。封装的主要目标是为类的用户建立一个强制的接口,并限制只对特定成员的直接访问。需要注意的是,定义类的接口意味着类的用户不需要直接修改或访问数据成员,而是调用公共方法,这些方法是为了对给定对象进行这些操作。

访问控制一般有三个关键词:publicprivateprotected。在 public 属性之后定义的成员对该类的所有用户都可以访问。另一方面,private 指定符定义了只有类的成员函数才能访问的成员。在下面的例子中,来自 main 函数的代码可以声明一个类型为 CustomString 的变量,但要访问它的成员 str,代码需要调用定义为 public 属性的 getString 方法。

#include <iostream>#include <string>#include <utility>#include <vector>using std::cout; using std::endl;
using std::vector; using std::string;
class CustomString {
public:
    CustomString() = default;
    explicit CustomString(const string &s):
            str(s) { num = s.size(); }
    virtual ~CustomString() = default;
    string& getString() { return str; };
private:
    string str;
protected:
    int num{};
};
int main()
{
    CustomString str1("Hello There 1");
    cout << "str1: " << str1.getString() << endl;
    exit(EXIT_SUCCESS);
}

输出:

str1: Hello There 1

使用 protected 属性来表示派生类或友类的成员函数可以访问的类成员

另一个可用于访问控制的关键字是 protected 属性,它使得类成员函数、派生类成员、甚至友类都可以访问之后声明的成员。注意,后面的两个不能直接从基类对象访问 protected 成员,而是从派生类对象访问。下一个例子演示了从 CustomString 派生出来的 CustomSentence 类,但后一个类的 num 成员是一个保护成员。因此,不能从 CustomString 对象中访问它。也就是说,getSize 函数不属于 CustomString 类,只有 CustomSentence 对象可以通过调用该方法来检索 num 值。

#include <iostream>#include <string>#include <utility>#include <vector>using std::cout; using std::endl;
using std::vector; using std::string;
class CustomString {
public:
    CustomString() = default;
    explicit CustomString(const string &s):
            str(s) { num = s.size(); }
    virtual ~CustomString() = default;
    string& getString() { return str; };
private:
    string str;
protected:
    int num{};
};
class CustomSentence : public CustomString {
public:
    CustomSentence() = default;
    explicit CustomSentence(const string &s):
            sent(s) { num = s.size(); }
    ~CustomSentence() override = default;
    int getSize() const { return num; };
    string& getSentence() { return sent; };
private:
    string sent;
};
int main()
{
    CustomString str1("Hello There 1");
    CustomSentence sent1("Hello There 2");
    cout << "str1: " << str1.getString() << endl;
    cout << "sent1: " << sent1.getSentence() << endl;
    cout << "size: " << sent1.getSize() << endl;
    exit(EXIT_SUCCESS);
}

输出:

str1: Hello There 1
sent1: Hello There 2
size: 13