Javier
Javier

Reputation: 1141

Friendship vs inheritance

I've the class hierarchy below. Basically, I would like to establish a "has-a" relationship between the classes Foo and CComplexMat, i.e. class Foo "has-a" CComplexMat. From what I know, private and protected members of a class cannot be accessed from outside the class where they are defined.

However, there are two possibilities to allow other classes to access such members. The first one is to use friend classes. I could add a line friend class Foo<T>; in the declaration of class CComplexMat<T>, so that Foo<T> can access the protected and private members of class CComplexMat<T>.

The second possibility would be to use inheritance, which is the solution that I've chosen in the example. In this case, I'm considering a public inheritance so that both public and protected members of class CComplexMat<T> are accessible in class Foo<T>. However, the following error is shown:

error: ‘CMatrix<float>* CComplexMatrix<float>::m_pReal’ is protected

error: within this context

  1. I was wondering if somebody could shed some light on the bug?
  2. In which situations are "friendships" or "inheritances" more suitable?
template <class T>
class CMatrix{
    public:
     ...
        CMatrix<T> & operator = (const CMatrix<T> &);
        T & operator()(int, int, int);
        T operator()(int, int, int) const;
     ...
    private:
       T *** pData;
       int rows, cols, ch;
};

template <class T>
class CComplexMat: public CMatrix<T>{
    public:
    ...
    protected:
        CMatrix<T> *pReal;
        CMatrix<T> *pImag;
};

template <class T>
class Foo: public CComplexMat<T>{
    public:
        ...
        void doSomething(){
           ...
           CMatrix<T>*pTmp = pComplex->pReal; // error here.
           ...
        }
    ...
    private:
        CComplexMat<T> * pComplex;
    ...
};

Upvotes: 3

Views: 3099

Answers (4)

UmmaGumma
UmmaGumma

Reputation: 5693

According C++ standard about access of protected members in derived classes (11.5)

Except when forming a pointer to member (5.3.1), the access must be through a pointer to, reference to, or object of the derived class itself (or any class derived from that class)

You are trying to access pReal through base class.

Make Foo friend of CComplexMat to access it's members.

Upvotes: 0

ThomasMcLeod
ThomasMcLeod

Reputation: 7779

You cannot access a protected member from outside a class, even if the class attempting the access is a sub class of the class that contains the protected member.

In your example, if pComplex would point to an object of type Foo, then you could access pReal in the way that you are attempting.

Upvotes: 0

aschepler
aschepler

Reputation: 72473

Inheritance should only be used for "is-a" relationships. It looks to me like CComplexMat<T> has two CMatrix<T> members, but it's not the case that it "is-a" CMatrix<T>. Similar deal with Foo and CComplexMat<T>.

So inheritance is almost certainly not the correct solution. That leaves:

  • Use friend to allow access between closely related classes.
  • Use public accessor methods to allow users of a class to "get at" private members in limited ways.

For example, CComplexMat<T> should probably have private members for the real and imaginary parts but then also some accessors like:

public:
    const CMatrix<T>& realPart() const;
    CMatrix<T>& realPart();
    const CMatrix<T>& imagPart() const;
    CMatrix<T>& imagPart();

Upvotes: 4

nybbler
nybbler

Reputation: 4841

You are accessing a local variable for CComplexMat in your Foo class instead of just accessing the parent class to get the value of pReal.

This tutorial breaks down the difference between friendship and inheritance in C++.
Note how they accessed the member variables of the parent class directly, without a local member of the parent class type. This is likely what you want to do in your example.

Upvotes: 0

Related Questions