从静态方法访问 class 的私有成员变量

Accessing private member variables of a class from a static method

我可以使用对象实例(指向对象的指针)直接访问下面代码中显示的 class 的私有成员变量。根据我的理解,不应访问私人成员。有人可以帮忙解释一下这种行为背后的原因吗?

#include <iostream>

class myClass;
using myClassPtr = std::shared_ptr<myClass>;

class myClass {
public:
    myClass(unsigned int val) : m_val(val) {}
    ~myClass() {}

    static
    myClassPtr create(unsigned int val) {
        myClassPtr objPtr = nullptr;
        objPtr = std::make_shared<myClass>(val);
        if(objPtr) {
            std::cout << objPtr->m_val << std::endl;
        }
        return objPtr;
    }
private:
    unsigned int m_val;
};

int main () {
    myClassPtr objPtr = myClass::create(10);
    return 0;
}

输出

anandkrishnr@anandkrishnr-mbp cpp % g++ static_test.cc -std=c++11 -Wall -Werror
anandkrishnr@anandkrishnr-mbp cpp % ./a.out
10
static myClassPtr create(unsigned int val) {

create()myClass的一个静态方法,是这个class的成员。因此它有权访问其 class 的所有私有成员和方法。此权利不仅扩展到它自己的 class 实例,而且扩展到此 class.[=17= 的任何 实例]

As per my understanding private members should not be accessible.

...除了 class.

的成员

让我们为您的 class 创建一个完全没有意义的复制构造函数,默认情况下您将获得相同的复制构造函数:

myClass(const myClass &o) : m_val{o.m_val} {}

此复制构造函数在访问传入对象的 m_val 方面没有任何问题。完全一样的事情发生在这里。 m_val 是其 class 的私有成员。这并不意味着只有同一对象的实例才能访问其私有成员,这意味着 any [=33 的实例=] 或静态 class 方法,可以访问私有 class 成员。

class 上的访问修饰符的本质是限制 class 的成员 在 class 之外 的使用.

由于 create()myClass 中,create() 可以访问您已声明的 myclass 的任何私有成员(或实际上任何成员)。包括 m_val

例如,让我们做一个简单的 class,

如果你有代码:

class box {
private:
    int width;
    int height;
};
int main() {
    box b;
    b.width;

    return 0;
}

编译器会抛出错误: error C2248: 'box::width': cannot access private member declared in class 'box'

因为main()函数是在class之外声明的,所以,main()函数不允许访问class[=20]的私有成员=].

如果我们想访问 class 之外的宽度,我们需要让这些成员 public 允许程序中的所有其他内容看到这些成员:

class box {
private:
    int width;
    int height;
public:
    int pubWidth;
    int pubHeight;
};
int main() {
    box b;
    b.pubWidth;

    return 0;
}

这一次,我们尝试访问的成员是 public、(pubWidth) 允许外部函数、classes 等访问 [=20 的这些成员=]

在我看来,Programiz 有一篇关于 C++ 中的访问修饰符的很棒且易于理解的文章。我建议看一看。 link here.

注意事项:如果未指定,class 中的所有成员都是私有的,但构造函数、析构函数以及一些我无法想到的特殊用例除外.

希望一切顺利!