Dynamic Allocation Operator:Pointers to Derived Types, Pointers to Class Members, and References in C++
These concepts are important in C++ because they extend the use of pointers beyond ordinary variables and objects. Pointers to derived types are mainly used with inheritance and polymorphism, pointers to class members provide a way to refer to data members or member functions of a class, and references provide an alternative name (alias) for an existing variable or object.
1. Pointers to Derived Types
In C++, a pointer can point to an object of a derived class. More importantly, a base-class pointer can also point to an object of a derived class.
This is one of the fundamental mechanisms used to achieve runtime polymorphism.
Basic Concept
Suppose we have a base class Animal and a derived class Dog.
class Animal
{
public:
void eat()
{
cout << "Animal eats" << endl;
}
};
class Dog : public Animal
{
public:
void bark()
{
cout << "Dog barks" << endl;
}
};We can create a pointer to the derived class:
Dog d;
Dog *ptr = &d;Here:
dis an object of classDog.ptris a pointer toDog.ptrstores the address ofd.
We can access members using the arrow operator:
ptr->bark();
ptr->eat();Visual Representation
Conceptually:
Derived Object
+------------------+
| Dog d |
|------------------|
| Animal members |
| Dog members |
+------------------+
↑
|
Dog *ptr2. Base-Class Pointer Pointing to Derived Object
A particularly important feature is:
Animal *ptr;
Dog d;
ptr = &d;Although ptr is declared as Animal*, it can store the address of a Dog object because Dog is derived from Animal.
Animal
↑
|
Dog
Animal *ptr
|
↓
+-------------+
| Dog object |
+-------------+This is called upcasting.
Example
#include <iostream>
using namespace std;
class Animal
{
public:
void eat()
{
cout << "Animal eats" << endl;
}
};
class Dog : public Animal
{
public:
void bark()
{
cout << "Dog barks" << endl;
}
};
int main()
{
Dog d;
Animal *ptr = &d;
ptr->eat();
return 0;
}Output
Animal eatsNotice that:
ptr->eat();is valid because eat() belongs to the base class.
However:
ptr->bark();is not valid, because the static type of ptr is Animal*, and bark() is not a member of Animal.
Important Rule
Base *ptr = &DerivedObject;is allowed for public inheritance.
But:
Derived *ptr = &BaseObject;is not automatically allowed.
3. Pointers and Runtime Polymorphism
Pointers to derived types become especially useful when virtual functions are used.
Consider:
#include <iostream>
using namespace std;
class Animal
{
public:
virtual void sound()
{
cout << "Animal sound" << endl;
}
};
class Dog : public Animal
{
public:
void sound() override
{
cout << "Dog barks" << endl;
}
};
int main()
{
Dog d;
Animal *ptr = &d;
ptr->sound();
return 0;
}Output
Dog barksHere:
Animal *ptr = &d;The pointer is of type Animal*, but it points to a Dog object.
Because sound() is declared virtual, C++ performs dynamic binding and calls:
Dog::sound()rather than:
Animal::sound()Conceptual Flow
Animal
|
virtual sound()
↑
|
Dog
|
overridden sound()
↑
|
Animal *ptr
|
↓
Dog object
|
↓
Dog::sound() called4. Pointer to a Derived Class Directly
A derived-class pointer can access both inherited and derived-class members.
#include <iostream>
using namespace std;
class Person
{
public:
void displayPerson()
{
cout << "Person information" << endl;
}
};
class Student : public Person
{
public:
void displayStudent()
{
cout << "Student information" << endl;
}
};
int main()
{
Student s;
Student *ptr = &s;
ptr->displayPerson();
ptr->displayStudent();
return 0;
}Output
Person information
Student informationBecause ptr has type Student*, it can access members available through Student, including inherited public members.
5. Pointers to Class Members
A pointer to a class member is different from an ordinary pointer.
An ordinary pointer stores the address of an object or variable:
int *p;A pointer to a class member identifies a member belonging to a particular class:
int MyClass::*ptr;There are two important forms:
Pointer to a data member
Pointer to a member function
6. Pointer to a Data Member
Consider:
class Student
{
public:
int rollNo;
float marks;
};A pointer to the rollNo member can be declared as:
int Student::*ptr;The ::* operator is used to declare a pointer to a class data member.
Assigning a Member
ptr = &Student::rollNo;The complete example is:
#include <iostream>
using namespace std;
class Student
{
public:
int rollNo;
float marks;
};
int main()
{
Student s;
s.rollNo = 101;
s.marks = 85.5;
int Student::*ptr;
ptr = &Student::rollNo;
cout << s.*ptr << endl;
return 0;
}Output
101The important expression is:
s.*ptrIt means:
Access the member identified by
ptrfrom objects.
7. Operators Used with Pointers to Class Members
There are two important operators.
.* Operator
Used when we have an object.
object.*pointerExample:
s.*ptr->* Operator
Used when we have a pointer to an object.
objectPointer->*memberPointerExample:
Student *p = &s;
cout << p->*ptr;Comparison
| Situation | Operator | Example |
|---|---|---|
| Object + member pointer | .* | s.*ptr |
| Object pointer + member pointer | ->* | p->*ptr |
8. Complete Example of Data-Member Pointer
#include <iostream>
using namespace std;
class Student
{
public:
int rollNo;
float marks;
};
int main()
{
Student s;
s.rollNo = 101;
s.marks = 89.5;
int Student::*pRoll;
float Student::*pMarks;
pRoll = &Student::rollNo;
pMarks = &Student::marks;
cout << "Roll No: " << s.*pRoll << endl;
cout << "Marks: " << s.*pMarks << endl;
Student *ptr = &s;
cout << "Using object pointer:" << endl;
cout << "Roll No: " << ptr->*pRoll << endl;
cout << "Marks: " << ptr->*pMarks << endl;
return 0;
}Output
Roll No: 101
Marks: 89.5
Using object pointer:
Roll No: 101
Marks: 89.59. Pointer to a Member Function
C++ also allows a pointer to refer to a member function.
Consider:
class Student
{
public:
void display()
{
cout << "Student details";
}
};A pointer to this member function can be declared as:
void (Student::*ptr)();The member function is assigned using:
ptr = &Student::display;The function can then be called using an object:
(s.*ptr)();or an object pointer:
(ptrObject->*ptr)();Example
#include <iostream>
using namespace std;
class Student
{
public:
void display()
{
cout << "Student display function" << endl;
}
};
int main()
{
Student s;
void (Student::*ptr)();
ptr = &Student::display;
(s.*ptr)();
return 0;
}Output
Student display function10. References in C++
A reference is an alternative name or alias for an existing variable.
It does not create a separate object.
Syntax
data_type &reference_name = variable;Example:
int x = 10;
int &ref = x;Here:
x
+------+
| 10 |
+------+
↑
|
refBoth x and ref refer to the same integer object.
11. Example of Reference
#include <iostream>
using namespace std;
int main()
{
int x = 10;
int &ref = x;
cout << "x = " << x << endl;
cout << "ref = " << ref << endl;
ref = 25;
cout << "After modification:" << endl;
cout << "x = " << x << endl;
cout << "ref = " << ref << endl;
return 0;
}Output
x = 10
ref = 10
After modification:
x = 25
ref = 25When we write:
ref = 25;the original variable x is modified.
12. Reference as a Function Parameter
One of the most common uses of references is passing arguments by reference.
Without Reference
void change(int x)
{
x = 50;
}The function receives a copy, so the original variable is not changed.
With Reference
void change(int &x)
{
x = 50;
}Now x refers to the original variable.
Example
#include <iostream>
using namespace std;
void change(int &x)
{
x = 50;
}
int main()
{
int a = 10;
cout << "Before: " << a << endl;
change(a);
cout << "After: " << a << endl;
return 0;
}Output
Before: 10
After: 5013. Reference and Function Return
A function can also return a reference.
int& getValue(int &x)
{
return x;
}Example:
#include <iostream>
using namespace std;
int& getValue(int &x)
{
return x;
}
int main()
{
int a = 10;
getValue(a) = 100;
cout << a << endl;
return 0;
}Output
100Here, getValue(a) refers to a, so assigning 100 changes the original variable.
Important: A function should not return a reference to a local variable because that local object is destroyed when the function ends.
Incorrect:
int& test()
{
int x = 10;
return x; // Wrong
}14. References to Objects
References can also refer to objects.
class Student
{
public:
int rollNo;
};
int main()
{
Student s;
Student &ref = s;
ref.rollNo = 101;
cout << s.rollNo;
}Output
101Here:
Student Object
+-------------+
| rollNo =101 |
+-------------+
↑ ↑
| |
s refBoth s and ref refer to the same object.
15. Reference vs Pointer
Pointers and references both allow indirect access to objects, but they are not the same.
| Feature | Pointer | Reference |
|---|---|---|
| Declaration | int *p | int &r |
| Can be null | Yes | Normally no valid null reference |
| Can be reassigned | Yes | No, after initialization |
| Requires initialization | Not necessarily | Yes |
| Access value | *p | Directly use r |
| Address operation | &x | Reference itself is an alias |
| Supports pointer arithmetic | Yes | No |
| Can point to different objects | Yes | No |
| Common use | Dynamic memory, arrays, polymorphism | Function parameters, aliases |
Example
Pointer:
int a = 10;
int b = 20;
int *p = &a;
p = &b;The pointer can be changed to point to b.
Reference:
int a = 10;
int b = 20;
int &r = a;r remains an alias for a; it cannot later be made an alias for b.
16. Pointer to Derived Type vs Reference to Derived Type
Both pointers and references can be used with inheritance.
Pointer
Dog d;
Animal *p = &d;Reference
Dog d;
Animal &r = d;Both can refer to the Dog object through its Animal interface.
With a virtual function:
class Animal
{
public:
virtual void sound()
{
cout << "Animal sound";
}
};
class Dog : public Animal
{
public:
void sound() override
{
cout << "Dog barks";
}
};Both:
Animal *p = &d;
p->sound();and:
Animal &r = d;
r.sound();will invoke:
Dog::sound()because of runtime polymorphism.
17. Important Syntax Summary
Pointer to Object
Student s;
Student *p = &s;
p->display();Pointer to Derived Object
Dog d;
Animal *p = &d;Pointer to Data Member
int Student::*p;
p = &Student::rollNo;
cout << s.*p;Pointer to Member Function
void (Student::*p)();
p = &Student::display;
(s.*p)();Reference
int x = 10;
int &r = x;Reference Parameter
void display(int &x)
{
// x refers to original argument
}18. Key Points for Examination
A derived-class pointer can directly point to a derived-class object.
A base-class pointer can point to a derived-class object through public inheritance.
Base-class pointers are extensively used for runtime polymorphism.
A virtual function enables the appropriate overridden function to be selected at runtime.
A pointer to a class data member is declared using the
::*syntax..*is used with an object and a pointer-to-member.->*is used with an object pointer and a pointer-to-member.A pointer to a member function requires the complete member-function pointer type.
A reference is an alias for an existing object or variable.
A reference must normally be initialized when declared.
A reference cannot be reseated to refer to another object.
References are particularly useful for pass-by-reference and avoiding unnecessary copying.
A function should not return a reference to a local variable.
Pointers and references are important tools for implementing polymorphism, efficient parameter passing, and object manipulation.
Quick Revision
Pointers to Derived Types
↓
Inheritance + Polymorphism
↓
Base pointer → Derived object
Pointers to Class Members
↓
Data member → int Class::*
Function member → return_type (Class::*)()
References
↓
Alias of existing object
↓
int &r = x
↓
Useful for pass-by-reference
No comments:
Post a Comment