【问题标题】:Call a class function from within a child class从子类中调用类函数
【发布时间】:2011-12-07 10:51:00
【问题描述】:

假设 B 类的对象是 A 类的成员。

class B{
    //Definitions
}

class A{
public:
    A();
    B b_child;
    int some_function();
}

B 中定义的函数之一需要从其所有者(父?)A 调用(公共)函数。有没有直接的方法可以做到这一点?

到目前为止,我设法做到这一点的唯一方法是在类定义之外实现它:

A a_obj;
a_obj.b_child.setowner(&aobj);

告诉b_child谁是它的所有者。我不喜欢这个。我宁愿使用b_child 的一些内置方法来访问其父级(如果可能)。如果这不可能,我宁愿在B 的构造函数中直接传递所有者的地址,但我不知道如何在其定义中引用A 的地址。

【问题讨论】:

  • 这是一个很好的问题,尽管您应该知道“子类”在 C++ 中具有非常特殊的含义,与继承有关。

标签: c++ class


【解决方案1】:

没有内置方法可以获取变量的“所有者”,无论这意味着什么。您设置所有者的方法是正确的。此外,在 B 的构造中这样做也是一个正确的决定。示例代码:

class B
{
public:
    explicit B( A* owner ) : _owner( owner ) {}

    ...
private:
    A* _owner;
};

class A
{
public:
    A() : _child( this ) {}

    ...
private:
    B _child;
};

请注意,某些编译器可能会警告您在该上下文中使用this,但对于当前示例来说没问题。只要确保你没有从B 构造函数中调用任何A 成员函数,因为在那个阶段你得到的指针仍然指向一个未构造的对象。

【讨论】:

    【解决方案2】:

    我宁愿为 b_child 使用一些内置方法来访问其父级(如果可能的话)。

    不,不是。

    但我不知道如何在其定义中引用 A 的地址。

    你可以使用this指针。

    A() : b_child(this) { }
    

    【讨论】:

      【解决方案3】:

      您应该使用this 指针来引用自身内部的对象

      class B{
          //Definitions
      }
      
      class A{
      private:
          B b_child;
      public:
          A()
          { 
             b_child.set_owner(this);
          }
      }
      

      【讨论】:

        【解决方案4】:

        你应该像下面这样定义B

        template <class T, int N>
        class B
        {
        public:
          int example_func() { return static_cast<T&>(*this).some_function(); }
        };
        

        然后将B&lt;A&gt; 设为A 的子类(这样它就可以直接调用A)。

        class A : protected B<A,0>, protected B<A,1>
        {
            A();
            int some_function() { return 42; }
        };
        

        这被称为curiously recurring template pattern

        如果您不希望B 成为模板类,并且您只想将BA 一起使用,那么以下是可以的:

        template <int N>
        class B
        {
        public:
          int example_func() { return static_cast<A&>(*this).some_function(); }
        };
        
        class A : protected B<0>, protected B<1>
        {
            A();
            int some_function() { return 42; }
        };
        

        或者,如果您想使用 B 而不只是 A,但又不想将 B 设为模板类(例如,如果您想要指向 B 的指针集合),您可以做到以下几点:

        template <int N>
        class B
        {
        public:
          int example_func() { return some_function(); }
          virtual int some_function() = 0;
        };
        
        class A : protected B<0>, protected B<1>
        {
            A();
            int some_function() { return 42; }
        };
        

        这将在运行时解析some_function() 调用,并且需要将虚拟指针存储在您的类中。

        【讨论】:

        • 与其他答案中的方法相比有优势吗?
        • 您保存了一个指针,因为 B 是 A 的一部分(因此具有相同的地址),因此无需将指向 A 的指针存储在 B 中。
        • 好的,我花了一段时间,但我想我不能使用这些选项。虽然我没有在问题中指定,但我需要 A 包含 B 类的几个对象(每个对象都有独立的参数和变量)。我正确理解了这段代码,这是不可能的。不过,很高兴知道。
        猜你喜欢
        • 1970-01-01
        • 2019-05-10
        • 1970-01-01
        • 1970-01-01
        • 2011-04-02
        • 1970-01-01
        • 2016-05-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多