从基类派生类中C ++向量的可访问性

时间:2014-03-07 09:34:18

标签: c++ inheritance friend derived-class

以下示例简化了我的方案:

#include <iostream>
#include <vector>
using namespace std;
class C;
class A
{
  protected:
    C * cPointer;
    A();
    virtual void updateList() = 0;
    void callFunc();
};

class B : public A
{
  private:
    vector<int> list;
    void updateList();
  public:
    void callFromA();
};

class C
{
  friend class A;
  friend class B; // I want to get rid off this declaration
  private:
    int sum;
    void set_sum( int val );
  public:
    static C * getCPointer();
};

A::A()
{
  cPointer = C::getCPointer();
}

void A::callFunc()
{
  updateList();
}

void B::updateList()
{
  list.push_back(2);
  list.push_back(4); 
  int s = 0;
  for( unsigned int i=0; i<list.size(); i++ )
  {
    s += list[i];
  }
  cPointer->set_sum(s);
}

void B::callFromA()
{
  callFunc();
}

void C::set_sum( int val )
{
  sum = val;
  cout << "Sum at C is: " << sum << endl;
}

C * C::getCPointer()
{
  static C cPointer;
  return & cPointer;
}

int main( int argc, char ** argv)
{
  B b;
  b.callFromA();
  return 0;
}

这个例子很好用。但我想摆脱C类中的“朋友级B”声明并实现类似的功能。实际上我想拥有以下任何一种:

  1. 来自B :: updateList()的C :: set_sum()的可访问性,如果没有C类中的“朋友类B”声明,这是不可能的。

  2. A :: callFunc()中B :: list的可访问性,我可以将逻辑从B :: updateList推送到A :: callFunc(),这基本上意味着能够访问派生类中的列表基类。这样,由于C语中的“朋友类A”声明,我将能够访问A :: callFunc()中的set_sum()。

  3. 在没有涉及重大设计变更的情况下实现这一目标的任何想法都是可取的!

    谢谢!

2 个答案:

答案 0 :(得分:0)

我不确定我是否了解您的所有限制,但也许这对您更有效。基本上,您可以使用虚拟功能从B::list访问A。我已经评论了代码中的更改。

#include <iostream>
#include <vector>
using namespace std;
class A;

class C
{
    friend class A;
private:
    int sum;
    void set_sum(int val);
public:
    static C * getCPointer();
};

class A
{
protected:
    C * cPointer;
    A();
    virtual int getS() = 0;             // virtual function to calculate data from vector in derived class B
    virtual void updateList()
    {
        cPointer->set_sum(getS());      // A is friend of C, so you can access B data from A
    }
    void callFunc();
};

class B : public A
{
private:
    vector<int> list;
    void updateList();

    int getS()                          // concrete implementation to access vector data
    {
        int s = 0;
        for (unsigned int i = 0; i < list.size(); i++)
        {
            s += list[i];
        }
        return s;
    }


public:
    void callFromA();
};

A::A()
{
    cPointer = C::getCPointer();
}

void A::callFunc()
{
    updateList();
}

void B::updateList()
{
    list.push_back(2);
    list.push_back(4);
    A::updateList();                    // Call to super implementation
}

void B::callFromA()
{
    callFunc();
}

void C::set_sum(int val)
{
    sum = val;
    cout << "Sum at C is: " << sum << endl;
}

C * C::getCPointer()
{
    static C cPointer;
    return &cPointer;
}

int main(int argc, char ** argv)
{
    B b;
    b.callFromA();
    return 0;
}

答案 1 :(得分:0)

您无法在基类,句点内访问派生类的成员。手头的对象可能是基类,甚至是完全不相关的派生类,保证了“有趣”的连续性。任何要求这样做的设计都会被严重破坏,需要重新思考。

您可以使想要虚拟化的基类的成员函数,并在派生类中重新定义它以执行您想要的任何变换。同时,如果被调用,基类的贞洁成员可以拒绝,以一种理智的方式表明错误。这样你就可以保证不会发生任何不太可能发生的事情。