views:

168

answers:

5

From here,

Using inheritance, which of the following is not allowed

a) Changing implementation of operation in parent by the subclass

b) Using implementation of operation in parent class by the subclass

c) Using attributes in parent class by the subclass

d) Having operations is subclass which do not exist in parent class

e) None

Am not convinced with the answers in the above link, so trying to clarify here. Pls answer.

+6  A: 

The answer is e) none.

Alexander Rafferty
+4  A: 

I would say the answer is A.

You can't change the implementation of an operation in a parent class.

You may be able to override the implementation (if the operation was declared as virtual) or you may be able to hide the original implementation...but never actually change the provided implementation from the base class.

Consider the following:

class Parent
{
    public:
        virtual void sayHello() { count << "Hello World!"; }
}

class Child : Parent
{
    public:
       void sayHello() { cout << "42!"; }
}

Now take a look at the results:

// Will still say "Hello World!" because our child can never 
// change the parent's implementation
Parent* parent1 = new Parent();
parent1->sayHello();
Justin Niessner
If the question on that site had been posed in the form of a complete, syntactically-correct English sentence, then we could have a nitpick fight whether by "Changing implementation of operation in parent by the subclass" they mean (as you infer) that the base class operation is changed, or (as I suspect) that the derived class is different from the base class in that operation, hence "changed". Moral: don't work for people who try to ask clever-clever questions about C++, but can't use C++ terminology. "change" is ambiguous, "subclass" is something to do with Java ;-)
Steve Jessop
@Elanaher - Wha? So you're saying that even though I'm creating an instance of Parent (and not an instance of Child using a Parent pointer), it will use the implementation from the child?
Justin Niessner
@Steve Jessop - I totally agree. This question could mean many different things and mixes terminology like crazy.
Justin Niessner
Excellent, in that case +1 for calling out the interviewer, by giving an answer they think is wrong and then telling them why it's their own fault for asking a stupid question.
Steve Jessop
@Justin Niessner Sorry ; I am too tired and I've just misread your code (maybe because it seemed too obvious that changing the parent's implementation was impossible ; I thought that you wanted to say that hidding the parents implementation wasn't possible but... sorry again). I will change my vote asap (need an edition).
Elenaher
+1  A: 

"A" is the answer and here's why...

a - The parent operation can be overridden (replaced, in a sense) but cannot be changed.

#include <iostream>

class A {
public:
   A() {}
   virtual ~A() {}
   virtual void foo() {
      std::cout << "Hi, I'm A" << std::endl;
   }
};

class B : public A {
public:
   B() {}
   virtual ~B() {}
   virtual void foo() {
      std::cout << "Hi, I'm B" << std::endl;
   }
};

int main() {
   A* a = new B();
   a->foo();

   return 1;
}

The code above will print...

Hello, I'm B

B::foo() overrode A::foo() but did not change it.


b - Yes, a subclass can use the implementation of a method in a parent class. For example, if we change the B::foo() method in the above code to...

virtual void foo() {
   A::foo();  // <--------------------------NOTE the addition of this call
   std::cout << "Hi, I'm B" << std::endl;
}

...the program will print...

Hi, I'm A
Hi, I'm B

c - The subclass can use public or protected attributes of the parent class but not private attributes. For example:

#include <iostream>

class A {
public:
   A() : pub(1), pro(2), pri(3) {}
   virtual ~A() {}
   virtual void foo() {
      std::cout << "Hi, I'm A" << std::endl;
   }

   int pub;

protected:

   int pro;

private:

   int pri;
};

class B : public A {
public:
   B() {}
   virtual ~B() {}
   virtual void foo() {
      std::cout << pub << std::endl;
      std::cout << pro << std::endl;
      std::cout << pri << std::endl;  // <----COMPILE ERROR
   }
};

int main() {
   A* a = new B();
   a->foo();

   return 1;
}

That code will have a compile error on the line noted above because subclass B is attempting to access a private member of the parent class. There is an exception to this rule if another class is declared to be a friend but you should rarely, if ever, use the friend keyword.


d - Yes, a subclass can have opperations that the parent class does not have. For example:

#include <iostream>

class A {
public:
   A() {}
   virtual ~A() {}
   virtual void foo() {
      std::cout << "Hi, I'm A" << std::endl;
   }
};

class B : public A {
public:
   B() {}
   virtual ~B() {}
   virtual void foo() {
      std::cout << "Hi, I'm B" << std::endl;
   }

   virtual void otherFunc() {
      std::cout << "I'm a function that my parent class doesn't have." << std::endl;
   }
};

int main() {
   B b;
   A& a = b;

   a.foo();
   a.otherFunc();  // <--- COMPILE ERROR

   b.foo();
   b.otherFunc();  // <--- OK

   return 1;
}

In the example above, otherFunc() was added to subclass B. Attempting to call it from a reference to an A class will cause a compile error. Calling it on a B class works as expected.


The best way to learn and know for sure is to try these things in a compiler. Try the code above. I tested it in Visual Studio 2008. The examples that aren't explicitly labeled with COMPILE ERROR should work.

dgnorton
I think option A "Changing implementation of operation in parent by the subclass" is just poorly worded, making the question ambiguous. A case could be made for either A or E, depending on how you interpret A.
Bill the Lizard
Bill the Lizard, you're probably right but I think (read: just my opinion) that someone new to C++ would likely interpret it such that "A" would be correct. I tried to make a distinction between "changing" and "overriding" (replacing) in my answer.
dgnorton
A: 

I would say E. I think I see what Justin is saying about item A, but in his example, inheritence is a red herring, and I think he's looking for a trick that's not there.

Creating a child with overriding behavior won't affect the parent if the child is not used, but that would seem to go without saying. If you changed the parent1 instance of the Parent to use the child's constructor instead, I think you would see that point A would be affirmed.

Steven
A: 

Using inheritance, which of the following is not allowed a) Changing implementation of operation in parent by the subclass

This isn't allowed. You can override virtual functions such that the subclass objects, when accessed via a pointer or reference to the base class, run their own implementations of those functions, but you can't stop an instance of the base class from running its normal implementation.

(Technically, if the base class defines member function templates, you can define a new specialisation and it will take affect from the point of definition to the end of that translation unit, but that's a nasty hack and not really the intension of templates).

b) Using implementation of operation in parent class by the subclass

This is only allowed for public/protected members - not private members.

c) Using attributes in parent class by the subclass

This is only allowed for public/protected members - not private members.

d) Having operations is subclass which do not exist in parent class

This IS unambiguously allowed, and impossible to restrict.

So, a) is the most unambiguously unallowed answer, while b) and c) can be allowed or disallowed using access specifiers in the base class declaration. d) is definitely allowed.

Tony