简体   繁体   中英

Accessibility of C++ vector in derived class from base class

My scenario is simplified in the following example:

#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;
}

This example works fine. But I want to get rid of the "friend class B" declaration in class C and achieving similar functionality. Actually I want to have either of the following:

  1. accessibility of C::set_sum() from B::updateList() which will not be possible without the "friend class B" declaration in class C.

  2. accessibility of B::list in A::callFunc() whereby I can push the logic from B::updateList to A::callFunc() which basically means ability to access a list in the derived class from the base class. In this way, I will be able to access the set_sum() in A::callFunc() due to "friend class A" declaration in class C.

Any idea to achieve this without involving major design changes is desirable!

Thanks!

I'm not sure if I understand all your restrictions, but maybe this works better for you. Basically, you can access B::list from A using a virtual function. I've commented the changes in the code.

#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;
}

You can not access members of derived classes inside the base class, period. The object at hand might be of the base class, or even of a completely unrelated derived class, with guaranteed "interesting" consecuences. Any design asking for doing so is seriously broken, and needs rethinking.

You can make the member function of the base class which wants to do so virtual, and redefine it in the derived class to do whatever perversion you have in mind. Meanwhile, the chaste member of the base class can just refuse if called, signalling the mistake in a sane way. That way you get a guarantee that nothing too untoward can happen.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM