lucas clemente
lucas clemente

Reputation: 6389

C++ Call private / protected function of a common base class

Is there a nice way to call A::foo() from B::bar() in the following sample?

class A {
protected:
  void foo() {}
};

class B : public A {
public:
  void bar(A& a) { // edit: called with &a != this
    a.foo(); // does not work
  }
};

I can't think of anything other than declaring B to be a friend of A, but that could get pretty ugly with some more classes.

Any ideas?

Upvotes: 3

Views: 6891

Answers (3)

MartinP
MartinP

Reputation: 768

Here's an approach to giving "protected" like access, allowing calls by any derived classes or object. It uses a protected token type, required to un-lock privileged methods:

struct A
{
protected:
    //Zero sized struct which allows only derived classes to call privileged methods
    struct DerivedOnlyAccessToken{};

public:     //public in the normal sense :
    void foo() {}

public:     //For derived types only :
    void privilegedStuff( DerivedOnlyAccessToken aKey );
};

struct B: A
{
    void doPrivelegedStuff( A& a )
    {
        //Can create a token here
        a.privilegedStuff( DerivedOnlyAccessToken() );
    }
};

int _tmain(int argc, _TCHAR* argv[])
{

    A a;
    a.foo();
    a.privilegedStuff( A::DerivedOnlyAccessToken() ); // compile error.

    B b;
    b.doPrivelegedStuff( a );

    return 0;
}

This is not my idea. I read it some place. Sorry I dont recall who's cunning idea it was.

I expect the compiler can elide the aKey parameter.

Upvotes: 1

Puppy
Puppy

Reputation: 146940

Yes, you can use a base-class function.

class A {
protected:
  void foo() {}
  void do_other_foo(A& ref) {
      ref.foo();
  }
};

class B : public A {
public:
  void bar(A& a) { // edit: called with &a != this
    this->do_other_foo(a);
  }
};

Upvotes: 4

BЈовић
BЈовић

Reputation: 64223

Why are you passing object of type A? You could do like this :

class B : public A {
public:
  void bar() {
    foo();
  }
};

or, like this

class B : public A {
public:
  void bar() {
    A::foo();
  }
};

Upvotes: 4

Related Questions