开发者

C++ Typing and OOP child classes

I'm a bit confused:

  • If I have 开发者_运维知识库a base class A, and a class B which extends A, can a variable of the type A hold a value of the type B and vice versa?

If yes, why? Aren't they completely different even if B is derived from A? How about type-safety?

  • If this is possible, what things do I have to mind when taking use of this? How would this work out in terms of performance?

Note: Sorry if I asked too many questions, just ignore them and just look out for those "marked" with the list decoration dot :) Also, this is not my homework. I'm a hobby programmer and have skills in scripting languages with OOP, yet I'm relatively new to OOP typing in C++.


If you do this:

B b;
A a = b;

then you get "slicing". a will contain just the A part of b.

But you can have references/pointers:

B b;
A &ra = b;
A *pa = &b;

In this case, ra and pa just refer/point to the real B object. This is because public inheritance models an IS-A relation. This is easier to understand with more descriptive names. Think of A and Animal and B as Baboon. A Baboon IS-A Animal so by using references/pointers, you can treat a Baboon as it's more generic Animal type.


A pointer or reference to an object of class A can point/refer to an object of class B. That's because if B derives from A, then a B is-a A. Each object of class B has all the member variables and functions of class A, plus those unique to B.

class A
{
   public:
      virtual ~A();
      void foo();
};

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

A * a = new B;
a->foo(); // perfectly valid, B inherits foo() from A
//a->bar(); // compile-time error, bar() is only defined in B
delete a; // make sure A has a virtual destructor!

Usually, this sort of code is used when you want to make use of polymorphic behavior through virtual functions.


Not to be contrary, but performance is not the right question here. If you've decided that you're going to make an OO design, don't sacrifice the correct abstraction for performance concerns. Premature optimization is the root of all evil. Good luck!


A variable of type A can hold a value of type B (for certain definitions of "hold", as other answers explain), but definitely not vice-versa. To break out a standard example:

class Animal {};
class Dog : public Animal {};
class Cat : public Animal {};

This is legal, because Cat derives from Animal:

Cat c;
Animal& a = c;

This isn't:

Animal a;
Cat& c = a;

This is type-safe because you've defined it to be so; the whole point of inheritance is to allow this sort of thing to happen, so you can go on to call methods on a generic Animal variable without knowing what base class happens to be stored in it. As for the performance question, calling virtual methods is slower because deciding which method will actually be called (Cat::foo() versus Dog::foo(), for example, depending on the particular type of Animal stored in the variable) has to happen at run-time -- this is called dynamic dispatch. With non-virtual methods the decision can happen at compile time

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜