-2

I have two classes:

class A{
private:
    int a;
public:
    void display()
    {
        cout<<"A: "<<a;
    }
    A()
    {
        a=10;
    }
};
class B: public  A
{
private:
    int b;
    public:
    void display1()
    {
        cout<<"B: "<<b;
    }
    B()
    {
        b=15;
    }

};

What is the difference between A *a= new B and B *b = new B ? Object b can access the members of both classes A &B whereas object a can access members of class A only. However in the virtual destructor example given in: No Virtual constructors but virtual destructor or any other example for that matter, it is always shown base class creates an object of derived class. Why would this be useful? When obj a can access members of class A only, what is the need to create an object of class B?

I have not been able to think of a practical example for this.

Community
  • 1
  • 1
user1692342
  • 5,007
  • 11
  • 69
  • 128
  • http://www.cplusplus.com/doc/tutorial/polymorphism/ – Anton Savin May 19 '15 at 07:14
  • 1
    "it is always shown base class creates an object of derived class" - what do you mean by that? It doesn't make any sense to me. The need to create an object of `B` even though you only use an `A*` pointer is polymorphism: `a` can be used to call virtual functions defined by `B`. Your introductory book should explain that in detail. – Mike Seymour May 19 '15 at 07:14
  • In the examples I have seen the objects have been created in the form A *a = new B; How does this differ from A *a = new A – user1692342 May 19 '15 at 07:15
  • 1
    @user1692342: As the code suggests, one creates a `B` while the other creates an `A`. So, in the first case, you can call virtual functions defined by `B`; in the second case you can't (if it even compiles - base classes are typically abstract). – Mike Seymour May 19 '15 at 07:21
  • 1
    Super or base classes may or may not be abstract. There are many examples for both cases. – Ingo Schalk-Schupp May 19 '15 at 07:23
  • @Douba: Indeed, hence the "typically" qualification. There are indeed (occasional) uses for non-abstract base classes, although that usually indicates that the base class has multiple responsibilities and would probably be improved by refactoring into smaller classes. – Mike Seymour May 19 '15 at 07:34
  • I suppose you are right, Mike. It would probably be possible but bad coding style. Thanks for your clarification. – Ingo Schalk-Schupp May 19 '15 at 07:35

4 Answers4

1

I have not been able to think of a practical example for this.

It's called polymorphism, and it's arguably the most important aspect of OOP. A base class can define an interface using virtual functions; derived classes can override those functions to provide whatever behaviour they like. Users can interact with the base class, with no knowledge of the derived class(es), and still use the functionality of the derived class.

To provide an example, just change your base class to declare a virtual function:

virtual void display() {cout << "A\n";}

and change the derived class to override this, rather than declare an unrelated function with a different name:

void display() override {cout << "B\n";}

Now we can see the difference between an object of type A:

A a;
a.display();   // prints A

and one of type B, even when accessed via a pointer or reference to A:

B b;
A & a = b;
a.display();   // prints B
Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
1

Imagine this application. You have a shape class (base) and two rectangle and trangle classes(derived). How you gonna calculate area of each shapes, from a base class function.

class shape {
  protected:
    int width, height;
  public:
    void set_values (int a, int b)
      { width=a; height=b; }
    //look this method is virtual and is implemented in derived classes
    virtual int area () 
      { return 0; }
};

class Rectangle: public shape  {
  public:
    int area ()
      { return width * height; }
};

class Triangle: public shape  {
  public:
    int area ()
      { return (width * height / 2); }
};

usage

shape* s1 = new Rectangle();
shape* s2 = new Triangle();

//set values accordingly

then you can call area function, and see which methods will invoke . . .

s1->area(); //area method of rectangle class
s2->area(); // area method of tangle class 

Hope you got it.

ANjaNA
  • 1,404
  • 2
  • 16
  • 29
0

It is a question of access from outside. While a allows its user to only access A's interface, b would allow its user to also access B's interface. You seem to understand this part already.

Your third question calls for another comparison: what is the difference between A *a = new B; and A *a = new A;? The difference here is that in the first exanmple, all of A's virtual methods in a are "replaced" by B's. This is called specialization. While you use the more general interface of the superclass A, the implementation at runtime is B's for virtual methods. As these methods, in general, rely on B's data structure, an object of class B must be instantiated.

Ingo Schalk-Schupp
  • 843
  • 10
  • 26
0
A* a = new B;

as well as

B* b = new B;

create an object on the heap. In the first case, functions defined in A can be accessed through the pointer a. If A has any virtual functions and they are implemented in B, then calling those functions on a will end up calling the functions in B. Any non-virtual function calls on a will call the functions defined in A.

In the second case, fucntions defined in B as well as those defined in A can be accessed through the pointer b.

In your case, you can use:

a->display();

as well as

b->display();

You can use

b->display1();

but you cannot use

a->display1();

If you replace display() and display1() by a virtual function, such as:

class A
{
   public:
      virtual display() { ... }
};

class B : public A 
 {
   public:
      virtual display() { ... }
};

Then, calling

a->display();

will end up calling B::display().

R Sahu
  • 204,454
  • 14
  • 159
  • 270