0% found this document useful (0 votes)
24 views24 pages

Unit - 2 Oocp

N

Uploaded by

raoh0605
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
24 views24 pages

Unit - 2 Oocp

N

Uploaded by

raoh0605
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 24

Unit-2

Q1. Write a short note on defining member functions.

Ans. A member function in a class is a function that operates on the instances (objects) of that class.
It is defined inside the class and has access to the data members of the class. Member functions can
manipulate the data members, providing functionality specific to the class.

To define a member function in C++, we declare it within the class definition and then implement it
either inside or outside the class. When implemented outside, the scope resolution operator (::) is
used to link the function to its class.

Member functions play a crucial role in object-oriented programming by encapsulating behavior


along with data.

class MyClass {

public:

int data;

void display(); // Declaration of member function

};

void MyClass::display() { // Definition using scope resolution

cout << "Data: " << data << endl;

Q2. Demonstrate nesting of member function.

Ans. Nesting of member functions refers to calling one member function of a class from within
another member function of the same class. This allows for a more modular and organized code
structure, as one member function can perform part of the functionality while another handles a
different part.

Here’s an example demonstrating the nesting of member functions:

#include <iostream>

using namespace std;

class Calculator {

private:

int a, b;

public:
// Member function to input values

void inputValues() {

cout << "Enter two numbers: ";

cin >> a >> b;

// Member function to add numbers

int add() {

return a + b;

// Member function to display the result, nesting the add() function

void displayResult() {

int sum = add(); // Calling add() function from displayResult()

cout << "The sum is: " << sum << endl;

};

int main() {

Calculator calc;

calc.inputValues(); // Getting input from user

calc.displayResult(); // Displaying the result (nests the add() function)

return 0;

Explanation:

• inputValues() accepts two integers from the user.

• add() computes the sum of a and b.

• displayResult() calls add() from within its body to get the sum and then displays it.

This is an example of how member functions can interact by nesting one within another to create a
more structured flow
Q3. Explain private member function.

Ans. A private member function in a class is a function that can only be accessed or called from
within other member functions of the same class. It cannot be called directly from outside the class
or by any non-member functions or objects. Private member functions are typically used for internal
utility operations that should not be exposed to users of the class but are essential to the class’s
internal operations.

Key points:

• Access scope: Private member functions can only be accessed by other member functions of
the same class.

• Encapsulation: They help enforce encapsulation by hiding the internal workings of the class
from the outside world.

• Utility: They are often helper functions that assist public member functions but don’t need to
be directly accessible by objects of the class.

#include <iostream>

using namespace std;

class Box {

private:

int length, width, height;

int volume() {

return length * width * height;

public:

void setDimensions(int l, int w, int h) {

length = l;

width = w;

height = h;

void displayVolume() {

cout << "Volume: " << volume() << endl;

}
};

int main() {

Box b;

b.setDimensions(5, 4, 3);

b.displayVolume();

return 0;

Explanation:

• The function volume() is declared as private, so it can only be called from within the class,
such as by the public function displayVolume().

• If you try to call b.volume() directly in the main() function, it will result in a compile-time
error because volume() is a private member of the class.

This structure allows the class to maintain control over its internal logic and hide unnecessary details
from the user, promoting better design and security in object-oriented programming.

Q4. Explain memory allocation for object.

Ans. In C++, memory allocation for objects occurs when an object is created. This memory is used to
store the object's data members, and the size of the allocated memory depends on the type and
number of data members the object contains. Memory can be allocated either on the stack (for local
objects) or the heap (for dynamically allocated objects), and this affects the object's lifetime and
scope.

Types of Memory Allocation for Objects:

1. Static Memory Allocation (Stack):

o When an object is created as a local variable within a function or block (without


using pointers), memory is automatically allocated on the stack.

o The object is destroyed automatically when the function exits or the block scope
ends.

o Memory management is handled automatically by the compiler.

class MyClass {

int data;

};

int main() {

MyClass obj;

}
Dynamic Memory Allocation (Heap):

• Objects can be dynamically allocated at runtime using the new operator, which allocates
memory on the heap.

• Dynamically allocated objects persist until explicitly deallocated using the delete operator.

• This gives the programmer more control over the object's lifetime, allowing the object to
persist even after the function that created it ends.

class MyClass {

int data;

};

int main() {

MyClass* obj = new MyClass; // obj is allocated on the heap

// Memory must be manually deallocated

delete obj; // Deallocating memory

Breakdown of Memory Allocation:

• Stack Memory: Memory for objects allocated on the stack is automatically managed and
limited in size. It's faster but has a short lifetime, limited to the scope of the function.

• Heap Memory: Memory for dynamically allocated objects (using new) is allocated on the
heap, which is larger but must be manually managed by the programmer (using delete).

Memory Layout of an Object:

• When an object is created, memory is allocated for its data members.

• Memory size is determined by the types and number of data members (e.g., int, float, etc.).

• No memory is allocated for member functions, as they are shared among all instances of the
class.

class MyClass {

int a;

double b;

};

int main() {

MyClass obj;

}
Q5. Characterize static data members and static member functions.

Ans. In C++, both static data members and static member functions belong to the class rather than
any specific instance of the class. This means they are shared among all instances (objects) of the
class, and can be accessed without creating an object. Let's break down their characteristics:

1. Static Data Members:

• Shared by all objects: A static data member is shared among all instances of the class,
meaning there is only one copy of it for the entire class. All objects of the class can access
and modify this single shared variable.

• Class-level scope: Static data members exist at the class level, not at the object level. They
are declared inside the class but must be defined outside of the class (unless initialized in-
class in C++17 or later).

• Lifetime: The lifetime of a static data member extends for the entire duration of the program,
meaning it is created when the program starts and destroyed when the program ends.

• Access: Can be accessed using the class name (e.g., ClassName::staticMember) or through an
object, though the former is more common.

class MyClass {

public:

static int count;

MyClass() {

count++;

};

int MyClass::count = 0;

int main() {

MyClass obj1, obj2;

cout << "Number of objects: " << MyClass::count << endl; // Output: 2

return 0;

2. Static Member Functions:

• Class-level functions: Static member functions can be called without creating an object of the
class. They are associated with the class itself, not with any particular object.

• Cannot access non-static members directly: Since static member functions are not tied to any
instance, they cannot access non-static data members or non-static member functions
directly. They can only access static data members and other static member functions.
• No implicit this pointer: Unlike non-static member functions, static member functions do not
have an implicit this pointer because they do not operate on specific instances.

class MyClass {

public:

static int count;

MyClass() {

count++;

// Static member function

static int getCount() {

return count;

};

int MyClass::count = 0;

int main() {

MyClass obj1, obj2;

cout << "Object count: " << MyClass::getCount() << endl; // Output: 2

return 0;

Q6. What is the use of constructor?

Ans. A constructor is a special member function in a class that is automatically called when an object
of that class is created. Its primary purpose is to initialize the object's data members and set up any
necessary conditions for the object to function correctly. Constructors allow the creation of objects
with an initial state, ensuring that the object is ready for use as soon as it is instantiated.

Key Features of a Constructor:

1. Same name as the class: A constructor has the same name as the class it belongs to.

2. No return type: Constructors do not have a return type, not even void.

3. Automatic invocation: Called automatically when an object is created, no need to call it


explicitly.

4. Can be overloaded: Multiple constructors can be defined with different parameters


(constructor overloading) to allow different ways to initialize an object.

Types of Constructors:
1. Default Constructor:

o Takes no arguments and provides default initialization.

o If no constructor is explicitly defined, the compiler provides a default constructor

class MyClass {

public:

MyClass() { // Default constructor

cout << "Object created!" << endl;

};

2. Parameterized Constructor:

• Takes arguments to allow initialization with specific values.

class MyClass {

public:

int x;

MyClass(int val) { // Parameterized constructor

x = val;

};

3. Copy Constructor:
• Used to create a new object as a copy of an existing object.It takes a reference to an object
of the same class as a parameter.

class MyClass {

public:

int x;

MyClass(const MyClass &obj) { // Copy constructor

x = obj.x;

};
Uses of a Constructor:

1. Initialization: A constructor initializes data members when an object is created, ensuring that
the object starts in a valid state.

2. Setting up resources: Constructors can allocate resources (like memory, file handles, etc.)
that the object needs during its lifetime.
3. Encapsulation and abstraction: By using constructors, you can hide complex initialization
code from the user, allowing objects to be created simply and safely without exposing
unnecessary details.

Q7. Explain types of constructor.

Ans. In C++, there are several types of constructors that serve different purposes when creating and
initializing objects. These include:

1. Default Constructor

• A default constructor is a constructor that takes no arguments (or has default parameters)
and initializes objects with default values.

• If no constructor is explicitly provided in a class, the compiler automatically generates a


default constructor.

• Purpose: To initialize data members with default values when no specific values are provided.

class MyClass {

public:

int x;

MyClass() { // Default constructor

x = 0;

};

int main() {

MyClass obj;

cout << obj.x; // Output: 0

2. Parameterized Constructor

• A parameterized constructor is a constructor that takes one or more parameters to allow for
initializing an object with specific values provided by the user.

• Purpose: To initialize objects with custom values provided at the time of object creation.
class MyClass {

public:

int x;

MyClass(int val) { // Parameterized constructor

x = val;

};

int main() {

MyClass obj(10

cout << obj.x; // Output: 10

3. Copy Constructor

• A copy constructor is a special constructor that creates a new object as a copy of an existing
object. It takes a reference to an object of the same class as a parameter.

• If a copy constructor is not explicitly defined, the compiler provides a default copy
constructor that performs a shallow copy (bitwise copy of member values).

• Purpose: To create an object by copying the data members of another object, especially
useful when working with objects that manage resources like memory.

class MyClass {

public:

int x;

MyClass(int val) : x(val) {} // Parameterized constructor

// Copy constructor

MyClass(const MyClass &obj) {

x = obj.x;

};

int main() {

MyClass obj1(5);
MyClass obj2 = obj1; // Copy constructor is called

cout << obj2.x; // Output: 5

4. Destructor

• Although not technically a constructor, a destructor is related because it is automatically


invoked when an object is destroyed. It is used to free up resources allocated during the
lifetime of the object.

class MyClass {

public:

~MyClass() { // Destructor

cout << "Object destroyed";

};

5.onversion Constructor

• A conversion constructor is a constructor that takes a single argument of a different type and
converts that argument into an object of the class.

• Purpose: To allow implicit or explicit type conversions from one type to the class type.

class MyClass {

public:

int x;

// Conversion constructor

MyClass(int val) : x(val) {}

};

int main() {

MyClass obj = 10;

cout << obj.x; // Output: 10

}
Q8. Explain constructor overloading.

Ans. Constructor overloading in C++ refers to the ability to define multiple constructors in a class,
each having a different set of parameters. This allows objects to be initialized in various ways
depending on the needs of the user. Each overloaded constructor performs a similar task (object
initialization) but with different input, which provides flexibility in object creation.

Key Features of Constructor Overloading:

1. Same name, different signatures: All constructors must have the same name as the class but
differ in the number or types of parameters.

2. Multiple ways of initialization: By defining multiple constructors, you give users the ability to
initialize an object in different ways (e.g., with no parameters, with one parameter, or with
multiple parameters).

3. Constructor selection: The correct constructor is automatically selected by the compiler


based on the arguments passed when creating the object.

#include <iostream>

using namespace std;

class Rectangle {

private:

int length;

int width;

public:

// Default constructor

Rectangle() {

length = 1;

width = 1;

cout << "Default constructor called!" << endl;

// Parameterized constructor with one parameter

Rectangle(int l) {

length = l;

width = 1;
cout << "Parameterized constructor with one parameter called!" << endl;

// Parameterized constructor with two parameters

Rectangle(int l, int w) {

length = l;

width = w;

cout << "Parameterized constructor with two parameters called!" << endl;

// Display area of the rectangle

void displayArea() {

cout << "Area: " << length * width << endl;

};

int main() {

Rectangle rect1; // Calls the default constructor

rect1.displayArea(); // Output: 1 (1x1)

Rectangle rect2(5); // Calls the constructor with one parameter

rect2.displayArea(); // Output: 5 (5x1)

Rectangle rect3(4, 6); // Calls the constructor with two parameters

rect3.displayArea(); // Output: 24 (4x6)

return 0;

Benefits of Constructor Overloading:

1. Flexibility: Provides flexibility by allowing objects to be initialized in multiple ways.


2. Code readability: Makes code easier to read and maintain because it avoids creating multiple
classes or different methods for object initialization.

3. Default values: If different types of initializations are needed, constructor overloading


ensures that objects can be created with meaningful default values or specific values based
on user input.

class Person {

private:

string name;

int age;

public:

// Default constructor

Person() {

name = "Unknown";

age = 0;

// Constructor with only the name parameter

Person(string n) {

name = n;

age = 0;

// Constructor with both name and age parameters

Person(string n, int a) {

name = n;

age = a;

void displayInfo() {

cout << "Name: " << name << ", Age: " << age << endl;

}
};

int main() {

Person p1; // Calls the default constructor

Person p2("Alice"); // Calls the constructor with one parameter

Person p3("Bob", 25); // Calls the constructor with two parameters

p1.displayInfo(); // Output: Name: Unknown, Age: 0

p2.displayInfo(); // Output: Name: Alice, Age: 0

p3.displayInfo(); // Output: Name: Bob, Age: 25

return 0;

Q9. Explain dynamic constructor.

Ans. A dynamic constructor in C++ is a constructor that dynamically allocates memory for data
members during object creation using dynamic memory allocation functions like new. This is useful
when the size of the data is not known at compile-time and needs to be determined at runtime.

In a dynamic constructor, memory for data members (typically arrays or objects) is allocated on the
heap, and the constructor manages this memory allocation.

Key Features of a Dynamic Constructor:

1. Dynamic memory allocation: Uses new (or malloc in C-style) to allocate memory for data
members during object creation.

2. Memory management: The constructor is responsible for allocating memory, and the
destructor should deallocate it using delete to avoid memory leaks.

3. Flexible object size: Objects can have data members whose size or quantity is determined
dynamically based on runtime information.

Steps in a Dynamic Constructor:

1. Memory Allocation: Allocate memory dynamically for the data members using new.

2. Initialization: Initialize the dynamically allocated memory (optional but recommended).

3. Deallocation (Destructor): Define a destructor to free the dynamically allocated memory


using delete or delete[].

Advantages of a Dynamic Constructor:


1. Flexible memory management: It allows creating objects that require dynamic memory
allocation, making it possible to handle large data structures whose size is only known at
runtime.

2. Efficient memory usage: Since the memory is allocated on the heap, large objects don't
occupy space on the stack, preventing stack overflow in cases of large data sizes.

3. Dynamic object sizing: It supports dynamic sizing of arrays or other data structures within
the class, providing flexibility for managing varying data sizes.

Disadvantages:

1. Manual memory management: The programmer is responsible for deallocating the


dynamically allocated memory using a destructor. If not done correctly, it may lead to
memory leaks.

2. Complexity: Managing dynamic memory can add complexity to the code and increase the
chances of errors such as memory leaks or invalid memory access.

Q10. Explain destructor.

Ans. In C++, a destructor is a special member function of a class that is automatically invoked when
an object of that class is destroyed (e.g., when it goes out of scope or is explicitly deleted). It is
primarily used to release resources that the object may have acquired during its lifetime, such as
memory, file handles, or network connections.

Key Features of a Destructor:

1. Same Name as the Class: The destructor has the same name as the class but is prefixed with
a tilde ~.

2. No Parameters: A destructor does not take any parameters and cannot be overloaded.

3. No Return Type: Destructors do not have a return type, not even void.

#include <iostream>

using namespace std;

class Demo {

public:

Demo() {

cout << "Constructor called!" << endl;

~Demo() {

cout << "Destructor called!" << endl;


}

};

int main() {

Demo obj; // Constructor is called here

return 0;

Output:

Constructor called!

Destructor called!

Use Cases of a Destructor:

• Freeing Dynamic Memory: If you dynamically allocate memory in the constructor, the
destructor should free it to prevent memory leaks.

• Closing Files/Connections: A destructor can ensure that files or database connections are
properly closed when the object is destroyed.

Q11. Which operators can’t be overloaded?

Ans. In C++, while many operators can be overloaded, there are a few that cannot be overloaded.
These operators have specific functionality tied to the language itself, and C++ does not allow
overloading for them.

Operators that cannot be overloaded:

1. Scope resolution operator (::)

o This operator is used to define a function or variable outside of a class or to specify


the namespace or class in which a member exists.

o Example: ClassName::functionName or std::cout.

2. Member access operator (.)

o The dot operator is used to access members of a class or struct object.

o Example: object.member.

3. Member pointer access operator (.*)

o This operator is used to access members of an object through a pointer-to-member.

o Example: (object.*pointer_to_member).

4. Conditional (ternary) operator (?:)


o The ternary operator evaluates a condition and returns one of two values based on
the result.

o Example: condition ? value_if_true : value_if_false.

5. Sizeof operator (sizeof)

o This operator returns the size (in bytes) of a data type or object.

o Example: sizeof(int).

6. Typeid operator (typeid)

o This operator is used in runtime type identification (RTTI) to get information about
the type of an object.

o Example: typeid(object).

7. Alignof operator (alignof)

o This operator returns the alignment requirements of a type.

o Example: alignof(type).

8. Cast operators (dynamic_cast, static_cast, reinterpret_cast, const_cast)

o These are used for type casting in different contexts. C++ provides explicit cast
operators that cannot be overloaded.

o Example: dynamic_cast<Type*>(ptr).

9. new and delete (placement versions)

o Although the standard new and delete operators can be overloaded, the placement
new and placement delete cannot.

o Example: void* operator new(size_t, void* p).

Q12. Write a program to demonstrate unary operator using member function.

Ans. #include <iostream>

using namespace std;

class Number

private:

int x;

public:

Number(int p)
{

x = p;

void operator -()

x = -x;

void display()

cout<<"x = "<<x;

};

int main()

Number n(10);

-n;

n.display();

return 0;

Q13. Rules for operator overloading.

Ans. Operator overloading in C++ allows you to redefine the behavior of operators for user-defined
types (like classes). However, there are several rules and guidelines you need to follow when
overloading operators.

1. Only Existing Operators Can Be Overloaded

• You cannot create new operators. Only the operators already defined in C++ can be
overloaded.

2. Overloading is Only for User-Defined Types


• Operators can be overloaded only for classes or structs. You cannot change the behavior of
operators for built-in types (e.g., you cannot overload int + int).

3. Operator Overloading Cannot Change Precedence or Associativity

• The precedence and associativity of an operator cannot be altered through overloading. The
overloaded operator will follow the same precedence rules as the original operator.

4. Some Operators Cannot Be Overloaded

• The following operators cannot be overloaded:

o Scope resolution (::)

o Member access (.)

o Member pointer access (.*)

o Conditional operator (?:)

o sizeof, typeid, alignof, decltype

o Type casting operators (static_cast, dynamic_cast, const_cast, reinterpret_cast)

5. Operator Function Must Be Either a Member or a Friend

• The overloaded operator function can either be:

o A member function of the class, or

o A non-member function (often defined as a friend function if it needs access to


private data members).

6. Unary Operators Take No Arguments or One Argument

• Unary operators (like -, !, ++, --) can be overloaded as either a member function with no
arguments or a non-member function with one argument.

7. Binary Operators Take One or Two Arguments

• Binary operators (like +, -, *, /) take one parameter when overloaded as a member function
and two parameters when overloaded as a non-member function.

8. Certain Operators Should Return by Reference

• Operators like assignment (=), subscript ([]), and compound assignment (+=, -=, etc.) should
return by reference to allow chaining and to prevent copying.

9. The Meaning of the Operator Should Be Intuitive

• It is recommended that the overloaded operator maintain its original intent. For example,
overloading the + operator should have a meaning related to addition.

10. Assignment, Subscript, Function Call, and Arrow Operators Must Be Members

• The following operators must be overloaded as member functions:

o Assignment operator (=)


o Subscript operator ([])

o Function call operator (())

o Member access through pointer (->)

11. Operators Involving Built-In Types Should Be Non-Member Functions

• If one of the operands is a built-in type and the other is a user-defined type, the operator
function should be a non-member function to ensure symmetry.

12. Overloading the = (Assignment) Operator

• The assignment operator (=) should handle self-assignment and correctly manage deep
copies if the object manages resources like dynamic memory.

13. Symmetry of Binary Operators

• When overloading binary operators like +, *, -, it’s often useful to ensure symmetry, meaning
both a + b and b + a should be valid if possible. This can often be achieved by overloading the
operator as a non-member function or providing both versions of the operator (for example,
int + MyClass and MyClass + int).

14. The Increment and Decrement Operators Have Two Forms

• You can overload both the prefix and postfix versions of ++ and --:

o Prefix form: ++obj (overload as operator++()).

o Postfix form: obj++ (overload as operator++(int); the int is a dummy argument used
to differentiate it from the prefix version).

Q14. Explain types of type conversion.

Ans. In C++, type conversion (also known as type casting) refers to the process of converting a value
from one data type to another. There are two main types of type conversion:

1. Implicit Type Conversion (Automatic Type Conversion)

Implicit type conversion happens automatically by the compiler when the data types involved are
compatible. It is performed when:

• The conversion is safe, meaning no loss of data or precision occurs (e.g., converting from int
to float).

• It is part of an arithmetic expression, or when assigning values from one type to another.

int a = 10;

double b = a; // Implicit conversion from int to double

Rules for Implicit Conversion:

• Widening conversions (e.g., int to float, float to double) are safe and commonly performed
automatically.
• Narrowing conversions (e.g., double to int, long to short) might lead to a loss of precision,
and though they might still happen automatically, they could cause unexpected results.

2. Explicit Type Conversion (Manual Type Conversion or Type Casting)

Explicit type conversion, also known as type casting, requires the programmer to manually specify
the conversion. It is used when implicit conversion is not provided or is undesirable.

Types of Explicit Type Conversion:

a) C-Style Casting

This is the simplest form of casting, similar to how it is done in C language.

double pi = 3.14159;

int a = (int) pi; // C-style cast

b) Function-Style Casting

Similar to C-style casting, but it uses a function-like syntax:

double pi = 3.14159;

int a = int(pi); // Function-style cast

Q15. How to declare/define class to basic type conversion?

Ans. In C++, you can define a class-to-basic type conversion by overloading a type conversion
operator, also known as a conversion operator. This allows an object of a class to be converted to a
basic data type (such as int, double, etc.).

Example: Class to int Conversion

In this example, we'll define a class Distance that holds distance in meters, and we'll provide a
conversion operator to convert an object of Distance to an int (which will return the distance in
meters).

#include <iostream>

using namespace std;

class Distance {

private:

int meters;

public:
// Constructor

Distance(int m = 0) : meters(m) {}

operator int() const {

return meters; // Returns the distance in meters

void display() const {

cout << meters << " meters" << endl;

};

int main() {

Distance d1(100);

int meters = d1;

d1.display();

cout << "Distance in int: " << meters << endl;

return 0;

Important Points:

• The conversion operator does not have a return type (even though it returns a value), as its
return type is implied by the type it converts to.

• It’s good practice to mark the conversion operator as const to ensure it does not modify the
object.
• If the conversion should be explicit (i.e., not automatic but manual), you can use the explicit
keyword to prevent implicit conversions and require the use of static_cast.

You might also like