0

I understand that friend is not inherited. I have classes Parent Person Child. Parent and Person are friends of each other. Parent has the following PROTECTED function...

class Person
{
    friend class Parent;
    public:
        Parent * parent;
}

class Parent
{
    friend class Person;
    protected:
        virtual void Answer() = 0;
}

class Child : public Parent
{
    void Answer()
    {
        std::cout << "Child!" << endl;
    }
}

My question is, if friendship is not inherited, how am I able to have the following...? (Person has a pointer to Parent)

Person person;
Child child;
person.parent->Answer();

Why is the output of this Child!, and it does not throw a runtime error when trying to access a virtual function?

I am confused as to how the child's function is being implemented, and the program is not erroring on run time since I would anticipate that it is trying to call Parent's virtual Answer function.

Joshua
  • 1,516
  • 2
  • 22
  • 31
  • Do you have any inheritance here? i.e. `class Child: public Parent` in you Child class definition? – Captain Giraffe Apr 18 '12 at 17:51
  • You are not calling any function on `Child` as I see in the Q. – Alok Save Apr 18 '12 at 17:52
  • 6
    Rather than describing your code, please post a trivial (but complete) code snippet. That way, we can all be clear about what your inheritance/friendship relationship is when answering. – Oliver Charlesworth Apr 18 '12 at 17:52
  • @Als So because I am calling Answer from type Parent, it's ok? Even though it's virtual and implemented by type Child? – Joshua Apr 18 '12 at 17:55
  • You need to show the code you are trying to figure out, then we can explain it easily. Without, we are lost. Edit your question to include the small but relevant samples. – Captain Giraffe Apr 18 '12 at 17:56
  • Without the code this is like shooting in the dark and i hate to do that because i might end up shooting my own foot.Post an code sample. – Alok Save Apr 18 '12 at 17:56
  • See my update. I assumed that you initialise `Person::parent` somewhere with something that points to a `Child`. – bitmask Apr 18 '12 at 18:12
  • error: 'virtual void Parent::Answer()' is protected – juanchopanza Apr 18 '12 at 18:13
  • Even after fixing the code, I cannot get that to compile. I really don't think you can do what you claim to be doing. – juanchopanza Apr 18 '12 at 18:16
  • See [here](http://ideone.com/NjKLh) – juanchopanza Apr 18 '12 at 18:18
  • @juanchopanza: From the context, I'm pretty sure `person.parent->Answer();` was meant as `this->parent->Answer();` or at least from within some `Person` context (perhaps not referencing `this` but a different `Person` object). – bitmask Apr 18 '12 at 18:25

1 Answers1

3

You are not accessing Child::Answer but Parent::Answer here, that's okay, because Parent is your friend. The fact that this is a Child object doesn't matter for that. However, it matters for what method will actually be invoked at runtime. Since Parent::Answer is virtual, overriding it with Child::Answer means that callers who have no clue what a Child is, will still be calling Child::Answer even when Child is accessed through a Parent reference or pointer (there is a layer of indirection that resolves the appropriate function at runtime).

You could even compile this before even implementing Child and later link against this .o file, handing it a Child instance, disguised as a Parent& or Parent*. Person will never have had the chance to even know that there is something called Child but still be able to "find" the correct implementation. That's the power of dynamic binding.

bitmask
  • 32,434
  • 14
  • 99
  • 159
  • What child object?? The call is to the Person's Parent object. – juanchopanza Apr 18 '12 at 18:15
  • @juanchopanza: Yes, I answered before OP added the declaration+implementation of the three classes. The question specifically asked how `Child::Answer` could be called from within a `Person` context. – bitmask Apr 18 '12 at 18:22