[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 298
  • Last Modified:

can a protected member of a baseclass be called on a different object in derived class?

class D is derived from class A. Class A has a protected method virtual foo(). In the implementation of a method of class D, is it allowed to use foo() on an object of class D, but different than this?
Other words,
D::anotherFoo()
{
D otherObject;
otherObject.foo(); //Is this allowed?
}

I get a compiler warning that the method foo is protected. So I ended up declaring D as a friend to B. Please clarify the concept/scope of protectedness here.
0
Prasad_Balakrishnan
Asked:
Prasad_Balakrishnan
  • 4
  • 3
  • 2
1 Solution
 
itsmeandnobodyelseCommented:
>>>> otherObject.foo(); //Is this allowed?

Yes, it compiles with VC6 and VC7.1 without problems. What warning did you get?

Regards, Alex
0
 
Prasad_BalakrishnanAuthor Commented:
I think  I forgot to mention that the method is accessed from base class.
Here is teh full code, if this is stored as a file.cpp, it throws compile error that void B::b1() is protected.
//Test.cpp start
class B
{
    protected:
    void b1();
};

class D : public B
{
    public:
        void d1();
};

void B::b1()
{
}

void D::d1()
{
    D otherD;
    otherD.b1();
    B otherB;
    otherB.b1();
    b1();
}
int main()
{  
}
//Test.cpp end
0
 
abithCommented:
instead of creating base class object and calling  method, try creating derv class object and call the method.
eg:
class base
{
protected:      void foo1()      {      }      
};
class der: public base
{
public :void foo2()
{
   der d;      
  d.foo1();
  }      
};



>> Other words,
D::anotherFoo()
{
D otherObject;
otherObject.foo(); //Is this allowed?
}

here this is possible, (assumption D is derived class and D does have the overridden method of foo())
are you sure that originally you tried creating object with class D, not C ?
 
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
abithCommented:
immediate posting!!
0
 
abithCommented:
>>here this is possible, (assumption D is derived class and D does have the overridden method of foo())
are you sure that originally you tried creating object with class D, not C ?

pls chage to :
here this is possible, (assumption D is derived class and D does'nt  have the overridden method of foo())
are you sure that originally you tried creating object with class D, not C ?
 
0
 
abithCommented:
>>  D otherD;
    otherD.b1();

your D class doesn't have b1()' s signature???
0
 
itsmeandnobodyelseCommented:
>>>> otherB.b1();
That is not valid cause class D member functions have the right to call B::b1() for D objects but not for B objects.

'protected' has the intention to give derived classes access to the protected member functions of their *own* baseclass object. When calling otherB.b1(); there is *no* baseclass object of class D involved, hence the error.
0
 
Prasad_BalakrishnanAuthor Commented:
Ok, I got it. Please let me ask one final extension of this question.
I can't copy my code here, so coming up with sample code.
I got this error when  I used base class pointer to access the protected method of base class (let's say b1()). But the object pointed to is really of derived class. This is because my findmethod only return base class pointers.
So, per your previous post, does that mean, I should dynamic_cast the base class pointer to derived class and only if succeeds, invoke b1() with the cast pointer?
I am modifying the above pasted code a bit to better explain my question:
void D::d1()
{
    D otherD;
    otherD.b1();
    B * otherB = findDObject();
    otherB->b1(); // Here otherB is REALLY an object of class D
}
0
 
itsmeandnobodyelseCommented:
>>>> otherB->b1(); // Here otherB is REALLY an object of class D

Yes, but that was determined at runtime and therefore the compiler does not know at compile time.

You better would call the

      B * otherB = findDObject();
      otherB->b1();

in a member function of B. The 'protected' issue only arises as you let the derived class *play* with baseclass pointers. But the dog should wag its tail and not vice versa.

    So if you would do:

    void D::d1()
    {
         D otherD;
         otherD.d2();
     }

    void D::d2()
    {
          b2();
    }

    void B::b2()
    {
           B* otherB = findObject(..);
           otherB->b1();
    }

all functions can be protected. Same happens if any member of B calls a virtual function. Once the call was made the 'this' has turened to a 'D' and the protected is no issue.

I think it is better to make B an abstract class where no instances can be created. You would do that by making b1() a pure virtual function which *must* be overloaded by derived classes.

class B
{
protected:
      virtual void b1() = 0;
};

Then, any derived class would call its 'own' overloaded function of b1. And only B member functions would handle B* pointers directly by using virtual calls only.

You even can make that:

class A
{
    int i;
protected:
    virtual void foo() = 0
    {  i = 2; }
};

class D : public A
{
    int m;
public:
    virtual void foo() {  A::foo(); }
    void foo2()
    {
        D d;
        d.foo();

    }
};

You see, A::foo() has an implementation though it is a pure virtual function. And more, that implementation was called by the (mandatory) overloaded D::foo(). And, 'protected' works fine here.

Regards, Alex
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

  • 4
  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now