简体   繁体   English

不了解私有/受保护的变量。 我的实现未达到我的预期

[英]Don't understand private/protected variables. My implementation didn't do what I expected

I am trying to learn about inheritance, and how private, protected, and public variables work. 我正在尝试了解继承,以及私有,受保护和公共变量的工作方式。

My understanding is that a class's private variables can only be read by members of that class, and that protected variables can be read by members of that class, and by derived classes. 我的理解是,一个类的私有变量只能由该类的成员读取,而受保护的变量只能由该类的成员以及派生类读取。

I am implementing some code to make sure that I understand this correctly, and I seem to be able to access variables that I didn't expect to be able to. 我正在实现一些代码,以确保我正确理解了这一点,而且我似乎能够访问我没想到能够访问的变量。

I have a class Polygon, and a derived class Triangle. 我有一个类Polygon和一个派生类Triangle。 I wrote a set of read() functions in the public areas of those classes to read their variables. 我在这些类的公共区域编写了一组read()函数来读取其变量。 These functions are overloaded so that with no arguments, read() will return the variables of the calling object, or alternatively, read(&Poly) can take another polygon as an argument and return the other polygon's variables. 这些函数被重载,因此不带任何参数的read()将返回调用对象的变量,或者,read(&Poly)可以将另一个多边形作为参数并返回另一个多边形的变量。

#include <iostream>
using namespace std;

class Polygon;
class Triangle;

class Polygon {
private:
    int privatePoly = 1;
protected:
    int protectedPoly = 10;
public:
    int publicPoly = 100;


    // Setters
    void setPrivate (int x) { privatePoly = x; }
    void setProtected (int x) { protectedPoly = x; }

    // Read
    int readPrivate (const Polygon& inPoly) { return inPoly.privatePoly; }
    int readProtected (const Polygon& inPoly) { return inPoly.protectedPoly; }
    int readPublic (const Polygon& inPoly) { return inPoly.publicPoly; }
};

class Triangle : public Polygon {
private:
    int privateTriangle = 3;
protected:
    int protectedTriangle = privateTriangle*10;
public:
    int publicTriangle = privateTriangle*100;


    // Read Triangle variables
    int readPrivate_Tri () { return privateTriangle; }
    int readProtected_Tri () { return protectedTriangle; }
    int readPublic_Tri () { return publicTriangle; }

    int readPrivate_Tri (const Triangle& inTri) { return inTri.privateTriangle; }
    int readProtected_Tri (const Triangle& inTri) { return inTri.protectedTriangle; }
    int readPublic_Tri (const Triangle& inTri) { return inTri.publicTriangle; }

};

I instantiated one object of each type, Polygon P1, and Triangle T1, and tried to read P1's private variables from the derived class T1, expecting this to fail since private variables shouldn't be readable by derived classes. 我实例化了每种类型的一个对象,即多边形P1和三角形T1,并尝试从派生类T1读取P1的私有变量,并期望这样做会失败,因为私有变量不能被派生类读取。 It didn't. 没有。

int main(int argc, const char * argv[]) {

    Polygon P1;
    Triangle T1;

    // To make sure T1's polygon variables are different from P1's.
    T1.setPrivate(2);
    T1.setProtected(20);

    // T1 reading P1
    cout << "T1.readPrivate(P1): " << T1.readPrivate(P1) << endl;
    cout << "T1.readProtected(P1): " << T1.readProtected(P1) << endl;
    cout << "T1.readPublic(P1): " << T1.readPublic(P1) << endl << endl;

    return 0;
}

This produces 这产生

T1.readPrivate(P1): 1 T1.readPrivate(P1):1
T1.readProtected(P1): 10 T1.readProtected(P1):10
T1.readPublic(P1): 100 T1.readPublic(P1):100

I thought perhaps this was related to the fact that the read functions were originally declared in the parent Polygon class (and that the private/protected specifiers referred to where the functions were declared rather than who the calling object was), so I gave the Triangle class its own copy of the readPolygon(&Polygon) variables. 我认为这可能与以下事实有关:读取函数最初是在父Polygon类中声明的(并且私有/受保护的说明符引用了声明函数的位置,而不是调用对象是谁),因此我给了Triangle类自己的readPolygon(&Polygon)变量副本。 The following was added to the definition of the Triangle class: 在Triangle类的定义中添加了以下内容:

// Read Polygon variables with separate function unique to Triangle class
int readProtected_P_from_T (const Polygon& inPoly) { return inPoly.protectedPoly; }
int readPublic_P_from_T (const Polygon& inPoly) { return inPoly.publicPoly; }

Where the readPublic_P_from_T() function was added to check the function format. 在哪里添加了readPublic_P_from_T()函数以检查函数格式。

This doesn't compile, with the error: "'protectedPoly' is a protected member of 'Polygon'" 这不会编译,并显示错误:“'protectedPoly'是'Polygon'的受保护成员”

I expected this to work because I thought a derived class could see protected variables. 我希望它能起作用,因为我认为派生类可以看到受保护的变量。

And I expected the first readPrivate function to not work, when called from the derived class. 当从派生类中调用时,我希望第一个readPrivate函数不起作用。

Could someone please explain how these access specifiers work? 有人可以解释一下这些访问说明符如何工作吗?

Any function within a class can access its private variables. 类中的任何函数都可以访问其私有变量。 It can access protected and public variables from iherited classes as well. 它也可以从继承的类中访问受保护的变量和公共变量。

If the function itself is public, anyone can call it. 如果函数本身是公共的,则任何人都可以调用它。

Usually private variables are used for internal needs of the class by its member functions and are not intended for the public. 通常,私有变量通过其成员函数用于类的内部需求,而不是面向公众的。 However, public member functions can use them for doing a particular action. 但是,公共成员函数可以使用它们来执行特定操作。

In your case all member functions are public. 在您的情况下,所有成员函数都是公共的。 Therefore, you can call them to access any internal data inside the class. 因此,您可以调用它们来访问类中的任何内部数据。

If you want to fail, try to access the member data directly without the function. 如果要失败,请尝试不使用该功能直接访问成员数据。 For example 例如

class A {
   int a = 0;
public:
   int b = 1;
   int getA() {
       return a;
   }
};


 A c1;
 cout << c1.a << c1.b;

the compiler will fail on the member access, because a is private. 编译器将在成员访问上失败,因为a是私有的。

On the other hand, if you use the getA() function, it will work, because the function itself can access private members: 另一方面,如果使用getA()函数,它将起作用,因为该函数本身可以访问私有成员:

cout << c1.getA() << c1.b;

My understanding is that a class's private variables can only be read by members of that class, and that protected variables can be read by members of that class, and by derived classes. 我的理解是,一个类的私有变量只能由该类的成员读取,而受保护的变量只能由该类的成员以及派生类读取。

That understanding is correct. 这种理解是正确的。

I instantiate one object of each type, Polygon P1, and Triangle T1, and tried to read P1's private variables from the derived class T1, expecting this to fail since private variables shouldn't be readable by derived classes. 我实例化了每种类型的一个对象,即多边形P1和三角形T1,并尝试从派生类T1读取P1的私有变量,并期望这样做会失败,因为私有变量不能被派生类读取。 It didn't. 没有。

readPrivate() is a member of Polygon , so it has no problem reading Polygon 's internals. readPrivate()Polygon的成员,因此读取Polygon的内部结构没有问题。

(Public) Inheritance allows Triangle to have these functions too, but since they are actually at the Polygon level, it doesn't have a problem. (公共)继承也使Triangle也具有这些功能,但是由于它们实际上处于Polygon级别,因此没有问题。

This doesn't compile, with the error: "'protectedPoly' is a protected member of 'Polygon'" 这不会编译,并显示错误:“'protectedPoly'是'Polygon'的受保护成员”

You are running into this situation . 您正在遇到这种情况 That link explains that problem and its answer far better than I could, so I'll leave it right there. 该链接比我能更好地解释该问题及其答案,所以我将其保留在那里。

Could someone please explain how these access specifiers work? 有人可以解释一下这些访问说明符如何工作吗?

You seem to have a pretty good grasp on the subject already, except with a few minor discrepancies. 除了一些小的差异外,您似乎已经对该主题有了很好的掌握。 However, if you wish to read up more on inheritance, here is a useful resource on it . 但是,如果您想了解有关继承的更多信息,这里是一个有用的资源

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM