【问题标题】:Can objects of derived classes in C++ be accessible by parent class?父类可以访问 C++ 中派生类的对象吗?
【发布时间】:2014-12-05 20:10:38
【问题描述】:

规则规定,在公共说明符的情况下 - 派生类的对象可以被视为基类的对象(反之亦然)。那是什么意思?

任何地方/任何地方都可以访问所有公共元素(在任何类中)吗?

这是否指的是父类定义为公共的属性和方法可由派生类访问。但是在派生类的属性和方法是公共的情况下,父/基类不能访问它们吗?

In a public base class 
Base class members                   How inherited base class members appear in derived class
private:   x ------------------------> x is inaccessible
protected: y ------------------------> protected: y
public:    z ------------------------> public: z

但是反过来呢?

【问题讨论】:

  • 如何从父类方法的代码中访问子类(非继承、非虚拟)成员?
  • 如果我有class Circle。我创建了一个 circle r; 的实例,例如访问公共属性 radius 是 r.radius。如果我在我的主要部分写,那么该属性必须是公开的。如果我想在派生类中访问相同的radius,为什么我不能这样做。因为那个方法/成员是公开的?
  • 简单的回答,是的,他们可以。更好的问题是“他们应该是吗?”。考虑到这一点的事实听起来很像需要重新考虑的设计,除非在一些非常罕见和特殊的情况下,甚至可能不会......
  • 他们可能不应该这样做。但我试图了解所有适用的规则 - 可以做什么 - 所以涵盖了所有场景。这就是为什么我不确定上面的反之亦然的说法。

标签: c++ class inheritance public


【解决方案1】:

我想正确的问题是“C++ 中派生类的成员非对象)可以被父类访问吗?”

派生类可以访问基类的公共和受保护成员(数据成员和函数)。

类的公共成员可以从任何地方访问。当然,它们需要通过该类的实例来访问。

但如果派生类的属性和方法是公共的,父/基类无法访问?

如果您有派生类的实例,它们可以是。然后,您可以从基类访问派生类的公共成员。


编辑:

基类成员访问派生类的公共成员的示例,反之亦然。

class Base
{
    public:
    void funcBase();
};

class Derived : public Base
{
    public:
    void funcDerived();

};

void
Base::funcBase()
{
    Derived d;
    d.funcDerived();
}

void
Derived::funcDerived()
{
    Base b;
    b.funcBase();
}

int main()
{
    Base b;
    Derived d;

    b.funcBase();
    d.funcDerived();
}

【讨论】:

  • 你说 - 一个类的公共成员可以从任何地方访问。在这种情况下,派生类中的方法如何不能访问父类的成员。这就是我的困惑所在。
  • 他们当然可以。这就是我所说的。这是一个示例,其中派生类成员访问基类的公共成员,而基类成员访问派生类的公共成员。类基{公共:无效funcBase(); };类派生:公共基础{公共:无效funcDerived(); }; void Base::funcBase() { 派生 d; d.funcDerived(); } void Derived::funcDerived() { Base b; b.funcBase(); } int main() { 基 b;导出d; b.funcBase(); d.funcDerived(); }
  • 我明白了。所以基类可以访问派生类中的方法。谢谢。
【解决方案2】:

你问:

C++派生类的对象可以被父类访问吗?

是的。下面是我见过几次的模式。

你还问过:

任何地方/任何地方都可以访问所有公共元素(在任何类中)吗?

是的,当然。

基类访问派生类成员的示例模式

Entity.h:

class Attribute;

class Entity
{
   public:
      Entity(Attribute* att);
      void save(FILE* fp);
      void print();

   private:
      Attribute* att_;
};

属性.h:

#include "Entity.h"

class Attribute : public Entity
{
   public:
      void save(FILE* fp);
      void print();

};

Entity.cc:

#include "Entity.h"
#include "Attribute.h" // Needed to access Attribute member functions

Entity::Entity(Attribute* att) : att_(att) {}

void Entity::save(FILE* fp)
{
   // Save its own data.
   //...

   // Save the Attribute
   att_->save(fp);
}

void Entity::print()
{
   // Print its own data to stdout.
   //...

   // Print the Attribute
   att_->print();
}

【讨论】:

    【解决方案3】:

    这意味着如果您有Bar,它是Foo 的派生类。

    class Foo
    
    class Bar : public Foo
    

    所以你可以说,正如预期的那样

    Foo* myFoo = new Foo;
    Bar* myBar = new Bar;
    

    您也可以从Bar 中创建一个Foo,因为BarFoo 的一种类型

    Foo* myOtherFoo = new Bar;
    

    您不能从Foo 中创建Bar,这就是“派生类的对象可以被视为基类的对象(反之亦然)”的意思。

    Bar* myOtherBar = new Foo;
    

    【讨论】:

    • 因此,如果我理解正确,您将无法从 Foo 访问 Bar。因为本质上 Foo 不是 Bar 的一种。但我的困惑在于公共变量。如果某些内容是公开的,则可以从 main 或任何其他随机函数访问它。为什么随机函数不能访问来自 Foo 的 Bar。
    • 因为它不知道它实际上是一个Bar。当我说Foo* myOtherFoo = new Bar; 时,每个公开使用myOtherFoo 的人只知道它是Foo。它也恰好是Bar,但没有人知道。对于Bar* myBar = new Bar;,您只能将其视为Bar,因为这实际上是指向Bar 的指针。
    猜你喜欢
    • 2017-01-16
    • 2020-08-23
    • 2022-07-20
    • 2014-12-05
    • 1970-01-01
    • 2015-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多