受保护的成员不能通过指针或对象 c++ 访问

Posted

技术标签:

【中文标题】受保护的成员不能通过指针或对象 c++ 访问【英文标题】:Protected member is not accessible through a pointer or object c++ 【发布时间】:2017-10-15 05:07:49 【问题描述】:

Visual Studio 告诉我我无法从父类的实例中访问成员变量。像这样的:

class Point
protected:
    int x, y;
;

class Quadrilateral : public Point

protected:
    Point A, B, C, D;
;

class Trapezoid : public Quadrilateral

public:
    bool isTrapezoid() 
        if (A.y == B.y && C.y == D.y)
            return true;
        return false;
    
;

据说Point::y 不能通过指针或对象访问。 谁能告诉我为什么?

【问题讨论】:

请贴出真实代码。 另外,“公共”继承(谢天谢地)不是真实的。 公共职能总是有点棘手! ;-) 在 Quadrilateral 中不需要继承 Point 类。无论如何,您都可以使用点对象。和受保护的成员可以从类和派生类访问。所以你可能需要公开 x,y 也许friend classes 就是您要找的。​​span> 【参考方案1】:

Point 有受保护的成员,难怪他们不能被访问。您应该将它们公开。

其他要点:

Quadrilateral 不应继承自 Point,因为这没有意义。 某些语法不是真正的 c++,您应该修复它(例如 class classisTrapezoid 参数列表中的代码。 使isTrapezoid 成为可以在Quadrilateral 上调用的方法,这应该是const 方法。 对于像这样的简单类,也许您应该公开所有成员(取决于您的代码设计)。
class Point

public:
    int x, y;
;

class Quadrilateral

public:
    Point a, b, c, d;

    bool isTrapezoid() const
    
        return a.y == b.y && c.y == d.y;
    
;

【讨论】:

【参考方案2】:

继承意味着您可以访问基类的受保护成员,这意味着在您的情况下 Point::y 可以在类中用作 Quadrilateral::y 和 Trapezoid::y ,但这并不意味着您可以访问y 来自任何其他 Point 对象,如果它们是成员,也不是。 从 Point 继承只是为了访问 A.y 是错误的。 所以 Trapezoid 可以访问 A 因为继承,但是不能访问 A.y 因为成员 A 的可访问性与问题中的继承无关。

正如 Michael Walz 评论的那样,如果您不希望 Point 的成员是公共的或通过成员函数访问,您可以将 Trapezoid 声明为 Point 的友元类,这使得 Point 的所有成员都可以访问 Trapezoid。但是,滥用它可能会导致意想不到的问题。

【讨论】:

以上是关于受保护的成员不能通过指针或对象 c++ 访问的主要内容,如果未能解决你的问题,请参考以下文章

c++ 默认移动赋值不能访问受保护的基成员

访问受保护或私有财产

Java中受保护的访问修饰符

通过基类变量访问的 C# 受保护成员 [重复]

C++类中的常成员和静态成员

除了这样,为啥我不能访问受 C# 保护的成员?