C++ Final
C++ Final
#include <iostream>
class MyClass {
private:
int* data;
int size;
public:
MyClass(int sz) : size(sz) {
data = new int[size];
for (int i = 0; i < size; ++i) {
data[i] = i;
}
}
MyClass(const MyClass &obj) : size(obj.size) {
data = new int[size];
for (int i = 0; i < size; ++i) {
data[i] = obj.data[i];
}
std::cout << "Copy constructor called" << std::endl;
}
~MyClass() {
delete[] data;
}
void display() {
for (int i = 0; i < size; ++i) {
std::cout << data[i] << " ";
}
std::cout << std::endl;
}
};
int main() {
MyClass obj1(5);
MyClass obj2 = obj1;
std::cout << "Contents of obj1: ";
obj1.display();
std::cout << "Contents of obj2: ";
obj2.display();
return 0;
}
4
#include <iostream>
class OuterClass {
private:
int outerData;
class InnerClass {
private:
int innerData;
public:
InnerClass(int data) : innerData(data) {}
void display() {
std::cout << "Inner data: " << innerData << std::endl;
}
};
public:
OuterClass(int data) : outerData(data) {}
void display() {
std::cout << "Outer data: " << outerData << std::endl;
}
void useInnerClass() {
InnerClass innerObj(42);
innerObj.display();
}
};
int main() {
// Creating an OuterClass object
OuterClass outerObj(10);
outerObj.display();
outerObj.useInnerClass();
return 0;}
destructors are invoked in the correct order, starting from the most derived
class and going up the inheritance chain.
Avoid Memory Leaks: If you delete an object through a pointer to a base class
and the base class destructor is not virtual, then only the base class
destructor will be called. This could lead to memory leaks if the derived class
has dynamically allocated resources that need to be released. By making the
destructor virtual, the correct destructor for the most derived class will be
invoked, ensuring that all resources are properly cleaned up.
#include <iostream>
class Base {
public:
Base() { std::cout << "Base constructor called" << std::endl; }
virtual ~Base() { std::cout << "Base destructor called" << std::endl; }
};
class Derived : public Base {
private:
int* data;
public:
Derived() : data(new int[5]) { std::cout << "Derived constructor called" <<
std::endl; }
~Derived() override {
delete[] data;
std::cout << "Derived destructor called" << std::endl;
}
};
int main() {
Base* basePtr = new Derived();
delete basePtr;
return 0;
}
Q7. What is the di erence between a base class pointer and derived class
pointer.
Ans: Base Class: A base class is a class in Object-Oriented Programming
language, from which other classes are derived. The class which inherits the
base class has all members of a base class as well as can also have some
additional properties. The Base class members and member functions are
inherited to Object of the derived class. A base class is also called parent
class or superclass.
7
Derived Class: A class that is created from an existing class. The derived
class inherits all members and member functions of a base class. The derived
class can have more functionality with respect to the Base class and can
easily access the Base class. A Derived class is also called a child
class or subclass.
#include <iostream>
using namespace std;
class Base {
public:
int a;
};
class Derived : public Base {
public:
int b;
};
int main()
{
Derived geeks;
geeks.b = 3;
geeks.a = 4;
cout << "Value from derived class: "
<< geeks.b << endl;
cout << "Value from base class: "
<< geeks.a << endl;
return 0;
}
8
Hybrid Inheritance:
Hybrid inheritance is a combination of multiple forms of inheritance,
including multiple, multilevel, or hierarchical inheritance.
It involves the inheritance of classes from multiple base classes in
di erent ways, resulting in a more complex inheritance structure.
This can include scenarios where a derived class inherits from multiple
base classes directly (multiple inheritance), as well as scenarios where
inheritance relationships form a hierarchical chain (multilevel
inheritance).
Hybrid inheritance allows for greater flexibility in class organization and
relationship modeling, but it can also lead to issues such as the
diamond problem in multiple inheritance.
Example: Class A is the base class, Class B and Class C are derived
from A, and Class D is derived from both B and C. Here, D inherits from
both B and C directly, creating a multiple inheritance relationship, and B
and C form a multilevel inheritance chain with A: A -> B, A -> C, B -> D, C
-> D.
Q11. Write a program to define classes A, B and C. The class C is derived
from A and B classes. Define count() member function in all the
classes as virtual. Count the number of object.
Ans: #include <iostream>
class A {
public:
static int objectCount;
A() {
objectCount++;
}
virtual void count() {
std::cout << "Class A Objects: " << objectCount << std::endl;
}
};
class B {
public:
static int objectCount;
B() {
objectCount++;
}
virtual void count() {
std::cout << "Class B Objects: " << objectCount << std::endl;
11
}
};
class C : public A, public B {
public:
static int objectCount;
C() {
objectCount++;
}
virtual void count() {
std::cout << "Class C Objects: " << objectCount << std::endl;
}
};
int A::objectCount = 0;
int B::objectCount = 0;
int C::objectCount = 0;
int main() {
A a1, a2;
B b1;
C c1, c2;
a1.count();
b1.count();
c1.count();
return 0;
}
cin>>n;
temp half;
int ans=half.solve(n);
cout<<ans<<endl;
}
#include <iostream>
class MyClass {
private:
int value;
public:
MyClass(int v) : value(v) {}
friend void printValue(const MyClass& obj);
};
void printValue(const MyClass& obj) {
std::cout << "Value: " << obj.value << std::endl;
}
int main() {
MyClass obj(42);
printValue(obj); // Output: Value: 42
return 0;
}
#include <iostream>
class Animal {
public:
void speak() {
std::cout << "Animal speaks" << std::endl;
}
};
class Dog : public Animal {
public:
void bark() {
std::cout << "Dog barks" << std::endl;
}
};
int main() {
Dog dog;
dog.speak();
dog.bark();
return 0;
}
2. Multiple Inheritance: Multiple Inheritance is a feature of C++ where a class
can inherit from more than one class. i.e one subclass is inherited from more
than one base class.
19
#include <iostream>
class Parent1 {
public:
void function1() {
std::cout << "Function 1 from Parent1" << std::endl;
}
};
class Parent2 {
public:
void function2() {
std::cout << "Function 2 from Parent2" << std::endl;
}
};
class Child : public Parent1, public Parent2 {
public:
void function3() {
std::cout << "Function 3 from Child" << std::endl;
}
};
int main() {
Child obj;
obj.function1();
obj.function2();
obj.function3();
return 0;
}
3. Multilevel Inheritance: In this type of inheritance, a derived class is
created from another derived class.
20
#include <iostream>
class Animal {
public:
void speak() {
std::cout << "Animal speaks" << std::endl;
}
};
class Dog : public Animal {
public:
void bark() {
std::cout << "Dog barks" << std::endl;
}
};
class Puppy : public Dog {
public:
void play() {
std::cout << "Puppy plays" << std::endl;
}
};
int main() {
Puppy puppy;
puppy.speak();
puppy.bark();
puppy.play();
return 0;
}
4. Hierarchical Inheritance: In this type of inheritance, more than one
subclass is inherited from a single base class. i.e. more than one derived class
is created from a single base class.
21
#include <iostream>
class Animal {
public:
void speak() {
std::cout << "Animal speaks" << std::endl;
}
};
class Dog : public Animal {
public:
void bark() {
std::cout << "Dog barks" << std::endl;
}
};
class Cat : public Animal {
public:
void meow() {
std::cout << "Cat meows" << std::endl;
}
};
int main() {
Dog dog;
Cat cat;
dog.speak(); // Inherits from Animal class
dog.bark();
cat.speak(); // Inherits from Animal class
cat.meow();
return 0;
}
5. Hybrid (Virtual) Inheritance: Hybrid Inheritance is implemented by
combining more than one type of inheritance. For example: Combining
Hierarchical inheritance and Multiple Inheritance.
22
#include <iostream>
class Animal {
public:
void speak() {
std::cout << "Animal speaks" << std::endl;
}
};
class Mammal {
public:
void feedMilk() {
std::cout << "Mammal feeds milk" << std::endl;
}
};
class Dog : public Animal, public Mammal {
public:
void bark() {
std::cout << "Dog barks" << std::endl;
}
};
int main() {
Dog dog;
dog.speak(); // Inherits from Animal class
dog.feedMilk();// Inherits from Mammal class
dog.bark();
return 0;
}
23
void display() {
std::cout << "Point: (" << x << ", " << y << ")" << std::endl;
}
};
int main() {
Point p1(3, 5);
p1.display();
return 0;
}
Copy Constructor:
A copy constructor is a constructor that initializes an object by making a
copy of another object of the same class.
It is called when an object is passed by value as an argument to a
function, returned by value from a function, or initialized with another
object of the same class.
#include <iostream>
class MyClass {
private:
int data;
public:
MyClass(int d) : data(d) {}
MyClass(const MyClass& other) {
data = other.data;
std::cout << "Copy constructor called" << std::endl;
}
void display() {
std::cout << "Data: " << data << std::endl;
}
};
int main() {
MyClass obj1(10);
MyClass obj2 = obj1;
obj1.display();
obj2.display();
return 0;
}
Destructor: Though not strictly a constructor, the destructor is a special
member function called when an object goes out of scope or is explicitly
deleted. It cleans up resources allocated by the object, such as memory or
file handles.
25
#include <iostream>
class MyClass {
public:
MyClass() {
std::cout << "Constructor called" << std::endl;
}
~MyClass() {
std::cout << "Destructor called" << std::endl;
}
};
int main() {
MyClass obj; // Constructor called
return 0;
}
int divisor = 0;
int result = 10 / divisor; // Division by zero will cause an exception
std::cout << "Result: " << result << std::endl;
} catch (const std::exception& e) {
std::cerr << "Exception caught: " << e.what() << std::endl;
} catch (...) {
std::cerr << "Unknown exception caught" << std::endl;
}
return 0;
}
Q21. Why abstraction is important in OOP? Discuss its importance with
suitable example.
Ans: Abstraction is a fundamental concept in object-oriented programming
(OOP) that involves simplifying complex systems by representing essential
features while hiding unnecessary details. It allows developers to focus on the
relevant aspects of a system, making it easier to understand, maintain, and
extend. Abstraction plays a crucial role in OOP for several reasons:
Simplification of Complex Systems: Abstraction enables developers
to focus on high-level concepts and ignore irrelevant details, thus
simplifying the understanding and management of complex systems. By
hiding implementation details, abstraction allows programmers to work
with simplified models of real-world objects or systems.
Modularity and Encapsulation: Abstraction promotes modularity by
encapsulating related data and behavior into a single unit, such as a
class. This allows for the creation of reusable components with well-
defined interfaces, reducing code duplication and improving code
organization and maintainability.
Enhanced Code Reusability: Abstraction encourages the creation of
reusable components with well-defined interfaces, making it easier to
reuse code across di erent parts of a system or in di erent projects. By
designing classes and interfaces that abstract away implementation
details, developers can create libraries and frameworks that can be
easily integrated into other projects.
Flexibility and Adaptability: Abstraction allows for the creation of
flexible and adaptable systems that can evolve over time. By designing
27
return 0;
}
Q23. Describe various stream classes for console I/O operations.
Ans: In C++, console input and output operations are performed using stream
classes provided by the C++ Standard Library, namely iostream. These
classes allow data to flow between the program and the console (standard
input/output streams).
Here are the main stream classes for console I/O operations:
std::cin:
The std::cin stream is the standard input stream, which is used to read
data from the console (keyboard) into the program.
It is associated with the standard input device (keyboard) by default.
It is typically used with extraction operators (>>) to read di erent types
of data from the console.
#include <iostream>
int main() {
int num;
std::cout << "Enter a number: ";
std::cin >> num;
std::cout << "You entered: " << num << std::endl;
return 0;
}
std::cout:
The std::cout stream is the standard output stream, which is used to
write data from the program to the console (standard output).
It is associated with the standard output device (console) by default.
It is typically used with insertion operators (<<) to write di erent types of
data to the console.
#include <iostream>
int main() {
std::cout << "Hello, World!" << std::endl; // Write "Hello, World!" to console
return 0;
}
std::cerr:
The std::cerr stream is the standard error stream, which is used to
output error messages and diagnostic information to the console.
It is similar to std::cout, but it is typically used for error reporting.
30
}
};
int main() {
Circle circle;
Rectangle rectangle;
Shape* ptrShape1 = &circle;
Shape* ptrShape2 = &rectangle;
ptrShape1->draw(); // Output: Drawing a circle
ptrShape2->draw(); // Output: Drawing a rectangle
return 0;
}
Q25. Describe the basic structure of a C++ program with all necessary
blocks.
Ans: A basic structure of a C++ program typically consists of several
essential blocks, including:
Preprocessor Directives: These are instructions to the compiler that
begin with a # symbol. They are processed before the actual
compilation of the code and are used to include header files, define
constants, and perform other preprocessing tasks.
Namespace Declaration: A namespace is a declarative region that
provides a scope for identifiers. It helps organize code and avoid naming
conflicts. The namespace keyword is used to define namespaces.
Main Function: Every C++ program must contain a main() function,
which serves as the entry point of the program. It is where the execution
of the program begins.
Variable Declarations: Variables are used to store data values. They
must be declared before they can be used in the program. Variable
declarations typically occur within functions or at the beginning of a
code block.
Executable Statements: Executable statements perform actions or
computations within the program. They can include assignments,
function calls, control flow statements (e.g., if, for, while), and other
expressions.
Function Definitions: Functions are named blocks of code that
perform specific tasks. They can be declared and defined within the
program to encapsulate functionality and promote code reuse.
Return Statement: The return statement is used to terminate the
execution of a function and return a value (if applicable) to the caller. In
the main() function, it indicates the successful execution of the
program.
32
#include <iostream>
using namespace std;
void greet();
int main() {
int age;
cout << "Enter your age: ";
cin >> age;
cout << "You entered: " << age << endl;
greet();
return 0;
}
void greet() {
cout << "Hello!" << endl;
}
Q26. Explain what are the methods used to create changes in subclasses.
Discuss with suitable example.
Ans: In object-oriented programming (OOP), changes in subclasses can be
made using inheritance, method overriding, and method overloading. These
techniques allow subclasses to modify or extend the behavior of their
superclass, providing flexibility and customization in class hierarchies.
Inheritance: Inheritance allows subclasses to inherit properties and
behaviors from their superclass. Subclasses can override inherited
methods, add new methods, or access superclass methods and
properties.
#include <iostream>
class Animal {
public:
void makeSound() const {
std::cout << "Animal makes a sound" << std::endl;
}
};
class Dog : public Animal {
public:
void makeSound() const {
std::cout << "Dog barks" << std::endl;
}
};
int main() {
33
Dog dog;
dog.makeSound();
return 0;
}
Method Overriding: Method overriding allows subclasses to provide
their own implementation for a method defined in the superclass. This
enables polymorphic behavior, where the appropriate method to call is
determined at runtime based on the actual type of the object.
#include <iostream>
class Animal {
public:
virtual void makeSound() const {
std::cout << "Animal makes a sound" << std::endl;
}
};
class Dog : public Animal {
public:
void makeSound() const override {
std::cout << "Dog barks" << std::endl;
}
};
int main() {
Animal* animal = new Dog();
animal->makeSound();
delete animal;
return 0;
}
Q27. Discuss the inline function with suitable example. Also write down
the limitations.
Ans: An inline function in programming is a function that is expanded in-line at
the point of call, rather than being executed through a function call
mechanism. This means that the compiler replaces the function call with the
actual code of the function, thereby potentially improving performance by
eliminating the overhead of a function call.
#include <iostream>
inline int add(int a, int b) {
return a + b;
}
int main() {
34
Object-oriented programming
There is no access specifier in
has access specifiers like private,
procedural programming.
public, protected, etc.
Adding new data and functions is Adding new data and function is
not easy. easy.
#include <iostream>
#include <fstream>
int main() {
std::ifstream inputFile("binary_data.bin", std::ios::binary);
if (inputFile.is_open()) {
char bu er[100];
inputFile.read(bu er, sizeof(bu er));
inputFile.close();
} else {
std::cerr << "Error opening file for reading." << std::endl;
}
return 0;
}
Writing to a Binary File:
To write to a binary file, you can use methods like write() to write binary
data directly from a bu er.
#include <iostream>
#include <fstream>
int main() {
std::ofstream outputFile("output_data.bin", std::ios::binary |
std::ios::out);
if (outputFile.is_open()) {
char bu er[] = "This is binary data.";
outputFile.write(bu er, sizeof(bu er) - 1); // Exclude null terminator
outputFile.close();
} else {
std::cerr << "Error opening file for writing." << std::endl;
}
return 0;
}
Seeking within a Binary File:
You can use methods like seekg() and seekp() to move the file pointer to
a specific position within the file for reading or writing.
#include <iostream>
#include <fstream>
int main() {
std::ifstream inputFile("binary_data.bin", std::ios::binary);
if (inputFile.is_open()) {
inputFile.seekg(10, std::ios::beg);
39
char bu er[100];
inputFile.read(bu er, sizeof(bu er));
inputFile.close();
} else {
std::cerr << "Error opening file for reading." << std::endl;
}
return 0;
}
Q32. What is operator overloading? Discuss unary operator overloading
with suitable example.
Ans: Operator overloading is a feature in object-oriented programming
languages that allows operators to be redefined or overloaded so that they
can be used with user-defined data types. This enables objects of a class to
behave like built-in data types regarding the use of operators.
Unary operator overloading specifically involves overloading unary operators,
which are operators that act on a single operand. Examples of unary operators
include ++, --, +, -, !, and ~.
Here's a discussion of unary operator overloading with a suitable example
in C++:
Unary Operator Overloading:
Unary operators are overloaded by defining member functions or friend
functions that take no arguments for the object on which they are invoked. The
unary operator functions can be defined as member functions or global
functions (friend functions) depending on whether they need access to private
members of the class.
#include <iostream> std::cout << "Count: " << count
class Counter { << std::endl;
private: }
int count; };
public:
Counter(int c = 0) : count(c) {} int main() {
Counter& operator++() { Counter c1(5);
++count; ++c1;
return *this; c1.display();
} return 0;
void display() { }