Tay2510
Tay2510

Reputation: 5978

Assign a pointer with the address of different data type without casting

I've never seen this kind of code before:

(Class B is a subclass of ClassA)

ClassB objB;
ClassA *ptrA = &objB; // Question1
ClassA objA = *ptrA // Question2

Question1:

Why this assignment is valid?

What's the difference compared to

Class B objB;
Class A *ptrA;
ptrA = (ClassA*)&objB;

or

ClassB  *ptrA;
ptrA = new classB;

Question2:

This line is valid too. Though the concept seems very similar to previous one but I don't know how it works.

Could anyone please tell me why these assignment are valid?

Upvotes: 0

Views: 119

Answers (4)

Jorma Rebane
Jorma Rebane

Reputation: 626

Regarding Question2, there are two possible outcomes here:

ClassA *ptrA = &objB;  
ClassA objA = *ptrA;   // Question2
  1. If no copy operator exists, only data fields from ClassA a scope are copied over and rest of the data is lost. This can be potentially dangerous, since the wrong vtable for virtual classes might be copied over. This is known as Object Slicing.
  2. If ClassA::operator=(const ClassA& rhs) exists, then the problem solves itself. Just make sure to implement correct logic in the copy operator.

If you don't take extra care with writing proper copy logic for your classes, your code will definitely break during runtime. I really recommend 'Effective C++' if you haven't picked it up yet - it gives a very good shortcut into the world of C++.

Upvotes: 1

Mike Seymour
Mike Seymour

Reputation: 254441

ClassA *ptrA = &objB; // Question1

Why this assignment is valid?

Because that's how polymorphic inheritance works. A ClassB is a ClassA; so a reference/pointer to ClassB can convert to a reference/pointer to ClassA.

ptrA = (ClassA*)&objB;

That's doing the same thing, but making the cast explicit. This is much more dangerous though - the evil C-style cast will allow any pointer conversion, whether or not it's valid, while the original implicit conversion will only allow safe conversions (as the derived-to-base pointer conversion is).

ptrA = new classB;

That creates a dynamic object, giving you a pointer to that; the original sets the pointer to point to an existing object. Don't use new unless you really need it.

ClassA objA = *ptrA // Question2

This is sometimes known as slicing. If the base class is copyable (as it presumably is here), then the base sub-object can be copied to make a new object of that type. Technically, *ptrA is converted to a reference to ClassA (since such a conversion is allowed, just as the previous pointer conversion is); then that reference is used to copy-initialise objA.

Slicing can cause confusion; but it's not an issue if you only use abstract base classes, since they can't be instantiated directly.

Upvotes: 1

This is called polymorphism. It is one of the most important key features of all object oriented programming languages.

Polymorphism means that instances of type B can be treated as instances of type A if B is derived from A.

Upvotes: 1

LearningC
LearningC

Reputation: 3162

In C++ a base class pointer can point to a oblect of derived class. This language rule makes these statements valid in C++.
First, this is allowed because this will not create any problem since accessing the oblect using base class pointer will not access any memory or function not defined. since anything defined in base class is also defined in subclass/derived class too.
This feature allows dynamic polymarphism. In which the derived classes can implement diffrent functionalities and a single base class pointer will invoke the functions for derived class objects and the function will be called depending on the typee of the object pointed by base class pointer. This feature wouldn't possible without allowing a base pointer point to derivd class object and invoke functions.

Upvotes: 3

Related Questions