1. BSCS³ CC-211 2024 Re-Sit Solved PP Spring
1. BSCS³ CC-211 2024 Re-Sit Solved PP Spring
In a problem domain description, objects can typically be identified by looking for nouns or
things that represent entities, concepts, or items with distinct characteristics and behaviors.
These are usually the "real-world" items the system is meant to model. Key steps to identify
objects include:
1. Look for nouns: Nouns often represent objects or entities. For example, in a banking
system, objects might include Account, Customer, Transaction.
2. Identify key entities: These are objects that will hold data (attributes) and have specific
behaviors (methods). For example, a Car object might have attributes like color and
model, and behaviors like start() or stop().
3. Consider interactions: Think about what entities interact with one another. These
interactions often imply objects, e.g., Order and Product interacting in an e-commerce
system.
4. Analyze relationships: Objects often have relationships with one another, such as "has-
a" or "is-a" relationships, e.g., a Student "has-a" Course.
In essence, objects are identified as entities with specific attributes and behaviors that interact
within the system.
How It Works:
Example:
class Account {
private:
double balance; // Private data member
public:
// Getter method
double getBalance() const { return balance; }
Benefits:
Yes, constructors can be overloaded in C++. Constructor overloading means having multiple
constructors with the same name but different parameter lists.
How it works:
Example:
class Rectangle {
public:
int length, width;
// Default constructor
Rectangle() {
length = 0;
width = 0;
}
// Parameterized constructor
Rectangle(int l, int w) {
length = l;
width = w;
}
};
In this example, the Rectangle class has two constructors—one that takes no parameters
(default) and another that takes two integers (length and width).
4. What are the static member functions? Are they of any use?
Static member functions are functions that belong to the class rather than any particular object.
They are defined using the static keyword and can be called without creating an instance of the
class.
Key Points:
1. Access: They can only access static data members of the class, not non-static members.
2. Usage: Called using the class name, not an object.
3. No Object Context: They don't require an instance of the class.
Usefulness:
Example:
class Counter {
private:
static int count;
public:
static void increment() { count++; }
static void display() { cout << "Count: " << count << endl; }
};
In this case, increment() and display() are static functions that can be called without creating
an object of Counter.
A pure virtual function is a function in an abstract class that has no definition and is declared
by assigning = 0 at the end of the function declaration. It forces derived classes to provide their
own implementation.
Purpose:
1. Enforces Overriding: Derived classes must implement the pure virtual function.
2. Abstract Classes: A class with at least one pure virtual function is abstract and cannot be
instantiated.
3. Polymorphism: Allows different derived classes to implement the function and enables
runtime polymorphism.
4. Interface Definition: Defines a contract for derived classes to follow, ensuring consistent
behavior.
Example:
class Shape {
public:
virtual void draw() = 0; // Pure virtual function
};
In this case, any class derived from Shape must implement the draw() function.
Long Question
write the implementation of a class named Binary having two data members (x
and y ) of type integer with private acess. Data member of this class should
contain 1 and 0 ( default value ) for a particular object.
1. write default and parameterized constructor.
2. write a standard implementation of overloaded arithematic assignment
operator.
3. write 'get Equal Binary' function which accept an array of Binary object with its
size and return a newly created array having all thoes object that are equal to the
left-handed-side (calling ) object. The function should also store the size of newly
created array into third parameter named newSize which is passed by referrence
to the function. the function should return NULL and store 0 in newSize, if all the
objects are different from left-handed-side (calling ) object.
The class Binary should initialize x and y with 1 and 0 by default, and allow parameterized
initialization to accept custom values constrained to 1 and 0.
#include <iostream>
#include <vector>
using namespace std;
class Binary {
private:
int x, y;
public:
// Default constructor
Binary() : x(1), y(0) {}
// Parameterized constructor
Binary(int xValue, int yValue) {
x = (xValue == 0 || xValue == 1) ? xValue : 1; // Ensure binary
values
y = (yValue == 0 || yValue == 1) ? yValue : 0; // Ensure binary
values
}
class Binary {
// Existing members...
public:
// Overloading += operator
Binary& operator+=(const Binary& rhs) {
// Binary addition with constraint
x = (x + rhs.x) % 2;
y = (y + rhs.y) % 2;
return *this; // Return the modified object
}
// Overloading -= operator
Binary& operator-=(const Binary& rhs) {
// Binary subtraction with constraint
x = (x - rhs.x + 2) % 2; // Ensure the result stays in {0, 1}
y = (y - rhs.y + 2) % 2;
return *this; // Return the modified object
}
};
3. getEqualBinary Function
This function filters objects from an array that are equal to the calling object.
class Binary {
// Existing members...
public:
// Equality operator for comparison
bool operator==(const Binary& obj) const {
return (x == obj.x && y == obj.y);
}
// getEqualBinary method
Binary* getEqualBinary(Binary arr[], int size, int& newSize) const {
vector<Binary> result;
return newArr;
}
};
Full Implementation
#include <iostream>
#include <vector>
using namespace std;
class Binary {
private:
int x, y;
public:
// Default constructor
Binary() : x(1), y(0) {}
// Parameterized constructor
Binary(int xValue, int yValue) {
x = (xValue == 0 || xValue == 1) ? xValue : 1;
y = (yValue == 0 || yValue == 1) ? yValue : 0;
}
// Getter methods
int getX() const { return x; }
int getY() const { return y; }
// Overloading += operator
Binary& operator+=(const Binary& rhs) {
x = (x + rhs.x) % 2;
y = (y + rhs.y) % 2;
return *this;
}
// Overloading -= operator
Binary& operator-=(const Binary& rhs) {
x = (x - rhs.x + 2) % 2;
y = (y - rhs.y + 2) % 2;
return *this;
}
// getEqualBinary method
Binary* getEqualBinary(Binary arr[], int size, int& newSize) const {
vector<Binary> result;
if (result.empty()) {
newSize = 0;
return NULL;
}
newSize = result.size();
Binary* newArr = new Binary[newSize];
for (int i = 0; i < newSize; ++i) {
newArr[i] = result[i];
}
return newArr;
}
};
int main() {
// Array of Binary objects
int size = 3;
Binary arr[] = {Binary(1, 0), Binary(0, 1), Binary(1, 0)};
// Calling object
Binary callingObject(1, 0);
if (equalObjects == NULL) {
cout << "No objects are equal to the calling object.\n";
} else {
cout << "Objects equal to the calling object:\n";
for (int i = 0; i < newSize; ++i) {
cout << "Object " << i + 1 << " - x: " << equalObjects[i].getX()
<< ", y: " << equalObjects[i].getY() << endl;
}
delete[] equalObjects; // Free dynamic memory
}
return 0;
}
Explanation:
1. Default and Parameterized Constructors initialize binary values properly.
2. Arithmetic Assignment Operators ensure operations like += and -= respect binary
constraints.
3. getEqualBinary dynamically creates an array of objects matching the calling object,
handles cases where no matches are found, and manages memory effectively.
This code ensures correctness, encapsulation, and efficient handling of binary operations.