3

I have seen this question http://www.careercup.com/question?id=384062

class Base {
public :
    virtual void method () = 0;
private :
    int n;
};

void Base::method() { n = 1;}

class D1 : Base {};

class D2 : public D1 {
    int i;
    void method() {i = 2;}
};

It passed the compiler of vs2008 and g++ 4.4.3

Here is my understanding of above code, please correct me if I am wrong

S1> D1 has inherited variable Base::n but it cannot access it.

S2> D1 has inherited the function Base::method but it doesn't call/modify this inherited function in the above implementation.

S3> D2::method is not an overridden version of D1::method

q0987
  • 34,938
  • 69
  • 242
  • 387
  • You might want to have a look at [this](http://stackoverflow.com/questions/5447498/what-are-access-specifiers-should-i-inherit-with-private-protected-or-public/%5d) – Alok Save Aug 12 '11 at 04:47

5 Answers5

2

S2 and S3 are wrong.

D1's methods can call it's Base::method(), but other code can't as Base part of D1 is private.

Base::method() is overridden by D2. If you somehow convert (new D2) to (Base*) and call Base::method, the i=2 code will run.

Considering access control, if you have pointer to Base*, external code can use ->method() because it's public, and if you have pointer to D2*, ->method() can't be called because it's private, even if it's the same object and the same method.

Also, despite your (n=1) implementation for Base::method() it and its class remain abstract.

hamstergene
  • 24,039
  • 5
  • 57
  • 72
1

In this case both Base and D1 classes are abstract classes which cannot be instantiated.

S1 - yes

S2 - Yes D1 has inherited the function. Can you please clarify your question.

S3 - No. D2::method is the override you have provided for the D2 class.

Edit: I just noticed the private inheritance of D1 from Base class. In that case, S1 and S2 still hold good.

Updated: S3: D2::method is both overriding and hiding the base class method.

Purnima
  • 992
  • 1
  • 8
  • 15
  • @Purnima: `D2::method` is overriding the `Base` class method `Base::method()` and it hides the Base class version of it, The method though not accessible in `D2` is still very much a part of it. – Alok Save Aug 12 '11 at 04:44
  • @Als: I think what you said would be true if it were public inheritance between classes `Base` and `D1`. – Purnima Aug 12 '11 at 06:11
  • @Purnima: It is true even if it is `private inheritance`. Access specifers dicate access rights of members which are part of the class, they do not control the presence or absence of members inside the class. – Alok Save Aug 12 '11 at 06:42
1

D1 has inherited variable Base::n but it cannot access it.
Correct.
Private members of a class are never accessible from anywhere except the members of the same class.


D1 has inherited the function Base::method but it doesn't call/modify this inherited function in the above implementation.
Correct, but conditonally, Read below for why:

D1 inherits the Base::method but it is not calling/invoking it because you did'nt add any statement to do so. But it can call it.
Pure virtual functions can have a body and they can be called by drived class members just like any other member function.

class D1 : Base 
{
    public:
        void doSomething()
        {
            Base::method();
        }

}; 

Note that in your Base class n is private so the only way to access it is through member function of Base & since only method() can do so, You can do it through it.

Note that presence of atleast one pure virtual function makes an class Abstract Class, And one cannot create objects of an Abstract class. Any class deriving from an Abstract class must override ALL the pure virtual functions of the Base class or else the derived class becomes an Abstract class as well.

Based on above rule,
In your case both Base and D1 are Abstract classes.


D2::method is not an overridden version of D1::method
Incorrect
Though method() is not acessible to the ouside world through instance of class D1, it is still very much a part of it. Access control dictates access rights not presence or absence of members.
So, Yes, D2::method is an overriden version of D1::method and it hides it as well, just that in this case, D1::method was not acccessible in the first place

Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • Can you please explain the third statement: "Though `method()` is not accessible inside the class `D1`". May I know why is this not accessible inside the class `D1`. Since `D1` privately inherits from class `Base`, `method()` is now a private member of class `D1`. Correct me if I'm wrong. – Purnima Aug 12 '11 at 06:09
  • @Purninma: That is a typo, I meant `method()` is not accessible to outside world through instance of `D1`. And as to your other query on my comment, As you yourself rightly said, `method() is now a private member of class D1`, so by redefining it, You are overriding and hiding the Base class version of `method`. – Alok Save Aug 12 '11 at 06:38
  • @Als, the calling of `Base::method()` can be simply written as method() since `method()` is a member of `D1`. – q0987 Aug 18 '11 at 14:53
  • @q0987: `method()` is a virtual function and hence it will be called through dynamic dispatch, Whether `Base::method()` will be called or `D2::method()`, will depend upon the type of object being pointer by the `Base pointer`, So, if you want to specifically call base class method irrespective of the actual object being pointed to is `Base` or `D1` then you will have to explicitly specify it as `Base::method()`. – Alok Save Aug 18 '11 at 15:57
0

S1: Correct

S2: Correct

S3: Correct, more clearly D2::method hides D1::method

LeleDumbo
  • 9,192
  • 4
  • 24
  • 38
0

S1 - Correct

S2 - Sorry I'm not very clear what you meant. In D1 or subclasses you can define method() to override it in Base but cannot call it. And, D1* cannot be converted to Base* because of private inheritance.

S3 - Incorrect. Once you declare a member function as virtual in the base class, it will keep virtual in subclasses even you leave out virtual. So in your case, method() in D2 is a overridden version of D1::method() and Base::method().

neuront
  • 9,312
  • 5
  • 42
  • 71