【问题标题】:access protected inherited member with pointer to base class使用指向基类的指针访问受保护的继承成员
【发布时间】:2013-04-12 11:01:38
【问题描述】:

谁能解释为什么这段代码不起作用。

class A
{
public:
    A(void){}
    virtual ~A(void){}
protected:
    A* parent;
};

class B : public A
{
public:
    B(void){parent = new B;}
    ~B(void){delete parent;}
protected:
    int a;
};

class C : public B
{
public:
    C(void){}
    virtual ~C(void){}
    void f(void){ ((B*)parent)->a; }
};

C 怎么可能无法访问B 的成员?

如果我将 parent 转换为 C* 而不是 B* 它工作正常。但我不希望用户承担任何不必要的风险。有没有更干净的方式访问a

谢谢。

【问题讨论】:

  • 我认为代码会在第一次创建 C 实例时崩溃,因为默认构造函数创建另一个实例作为父实例,然后创建另一个实例,然后创建...
  • @Axel:这当然只是真实代码的简化版本。但我更新了问题以避免混淆。

标签: c++


【解决方案1】:

C 类的对象,您可以访问B 的受保护成员,但前提是它们是C 类的某些对象的一部分(也许是你的,也许不是)。换句话说,要从C 访问a,您需要一个指向C 的指针(或引用)。这就是protected 修饰符的含义。

原因如下。 ((B*)parent) 指针可能指向B 的某个其他子类,与C 完全不同,并且该子类可能无法访问a 成员。

【讨论】:

  • 你能举个例子吗?
  • 如果不重新构建代码,我提出的任何建议都会变得很老套。您可以 1) 按照您的建议将 parent 转换为 C* 或 2) 使 B::a 可公开访问(可能通过某种方法)或 3) 使 C 成为 B 的朋友类。要制定更优雅的解决方案,您必须更多地了解您的实际代码(ABC 类只是没有提供足够的上下文)。
  • 我说的例子是:指针可能指向 B 的某个其他子类,与 C 完全不同,并且该子类的 a 成员可能无法访问。
  • 哦,对不起,我误会了。这个例子是parentclass D : public B { private: using B::a; }; 的一个实例。 a 成员无法通过D 访问,但可以通过B 访问。这是一个奇怪的设计,我知道,但这里的重点不是(不)可访问性,不是真的。而是B::a 在被子类继承时改变了它的含义。例如。如果你有class E : public B {};,那么在Ea 成员的解释可能与B 中的解释方式不同。
  • 我不太明白这个问题。 ((B*)parent) 是一个指向 B 的指针,它可以指向一些 D 的实例。您的代码中没有 D 的事实并不重要:它可以在其他地方声明 - 或者在运行时从动态库加载,就此而言。关键是,要访问从C 继承的受保护成员,您需要一个指向C 的指针。使用指向 B 的指针,不能保证它不会指向具有 B::a 的语义(或可访问性)发生变化的东西。
猜你喜欢
  • 2016-02-29
  • 2017-10-01
  • 2019-10-03
  • 2014-09-12
  • 2011-03-04
  • 1970-01-01
  • 2016-12-07
  • 1970-01-01
  • 2011-05-24
相关资源
最近更新 更多