AlgoDaily

Object Oriented Programming in C++

Read at your own pace. Code execution, quizzes, progress tracking, and the AI tutor are available in the interactive view with JavaScript enabled.

Classes and Objects

Classes and Objects

In C++, classes are used to define objects. A class is a blueprint that defines the properties and behaviors that an object of that class will have.

To define a class in C++, you can use the class keyword followed by the name of the class.

// Class definition

class Car {
    // Class members
};

The class can have attributes (properties) and methods (functions).

// Class definition

class Car {
    // Attributes
    string brand;
    int year;

    // Methods
    void start() {
        cout << "Starting the car" << endl;
    }
};

To create an object of a class, you can use the class name followed by the object name and optional parentheses.

// Create an object of the Car class
class Car myCar;

Once you have created an object, you can access its attributes and call its methods using the dot operator.

// Access the attributes and methods of the object
myCar.brand = "Toyota";
myCar.year = 2020;

myCar.start();
```c++
#include <iostream>
using namespace std;

// Define the `Car` class

// Class definition

// constructors

// methods

int main() {
    // Create an object of the `Car` class

    // Access the methods and properties of the object

    return 0;
}

```

True or False

Classes and objects are used to define attributes and behaviors in C++.

Inheritance

Inheritance

Inheritance is a fundamental concept in object-oriented programming (OOP) that allows you to create a new class (called the derived class) from an existing class (called the base class). The derived class inherits the properties and behaviors of the base class, and can also add its own unique properties and behaviors.

In C++, inheritance is defined using the : symbol followed by the access specifier (public, protected, or private) and the name of the base class.

// Base class

class Shape {
public:
    // Base class members
};

// Derived class

class Rectangle : public Shape {
public:
    // Derived class members
};

In the example above, Rectangle is the derived class and Shape is the base class.

By using the public access specifier, the derived class inherits the public members of the base class. In other words, the derived class can access and use the public members of the base class.

When an object of the derived class is created, it contains all the data members and member functions of the base class as well.

You can also override the base class member functions in the derived class to provide a different implementation. This is known as function overriding.

In the example below, the display() member function is overridden in the Rectangle class to provide a different implementation.

// Base class

class Shape {
public:
    void display() {
        cout << "This is a shape" << endl;
    }
};

// Derived class

class Rectangle : public Shape {
public:
    void display() {
        cout << "This is a rectangle" << endl;
    }
};

To create objects of the derived class, you can use the same syntax as creating objects of the base class.

Shape* shape = new Shape();
shape->display();

Rectangle* rectangle = new Rectangle();
rectangle->display();

When the display() function is called on the shape object, it will output "This is a shape". When the display() function is called on the rectangle object, it will output "This is a rectangle".

Inheritance allows for code reusability and helps in organizing and structuring the code in a logical manner. It is particularly useful in scenarios where you have common properties and behaviors shared among multiple classes, as it avoids code duplication and promotes a modular approach.

```c++
#include <iostream>
using namespace std;

// Base class

class Shape {
public:
    void display() {
        cout << "This is a shape" << endl;
    }
};

// Derived class

class Rectangle : public Shape {
public:
    void display() {
        cout << "This is a rectangle" << endl;
    }
};

int main() {
    Shape* shape = new Shape();
    shape->display();

    Rectangle* rectangle = new Rectangle();
    rectangle->display();

    return 0;
}
```

Inheritance Fill In

Inheritance is a fundamental concept in object-oriented programming (OOP) that allows you to create a new class (called the _________________) from an existing class (called the _________________). The derived class inherits the properties and behaviors of the base class, and can also add its own unique properties and behaviors.

Polymorphism

Polymorphism

Polymorphism, a key concept in object-oriented programming (OOP), refers to the ability of objects of different classes to be treated as objects of a common base class. This allows for code reuse and enables behavior to be determined at runtime.

In C++, polymorphism is achieved through the use of virtual functions. A virtual function is a member function of a class that can be overridden in a derived class.

To demonstrate polymorphism, let's consider an example involving animals. We have a base class Animal and two derived classes Dog and Cat. Each derived class has its own implementation of the makeSound() function.

// Base class

class Animal {
public:
    virtual void makeSound() {
        cout << "The animal makes a sound" << endl;
    }
};

// Derived class

class Dog : public Animal {
public:
    void makeSound() {
        cout << "The dog barks" << endl;
    }
};

// Derived class

class Cat : public Animal {
public:
    void makeSound() {
        cout << "The cat meows" << endl;
    }
};

In the main() function, we can create objects of type Dog and Cat and use a pointer of the base class type Animal to invoke the makeSound() function. This is where polymorphism comes into play.

int main() {
    Animal* animal;
    Dog dog;
    Cat cat;

    // Animal pointer pointing to a Dog object
    animal = &dog;
    animal->makeSound(); // Output: The dog barks

    // Animal pointer pointing to a Cat object
    animal = &cat;
    animal->makeSound(); // Output: The cat meows

    return 0;
}

As you can see, when we call the makeSound() function on the animal pointer, the appropriate implementation is invoked based on the actual object type. This behavior is determined at runtime, allowing for flexibility in the code.

Polymorphism is a powerful OOP concept that promotes code flexibility, extensibility, and modularity. It allows for the creation of generic code that can operate on objects of different classes as long as they inherit from a common base class.

```c++
#include <iostream>
using namespace std;

// Base class

class Animal {
public:
    virtual void makeSound() {
        cout << "The animal makes a sound" << endl;
    }
};

// Derived class

class Dog : public Animal {
public:
    void makeSound() {
        cout << "The dog barks" << endl;
    }
};

// Derived class

class Cat : public Animal {
public:
    void makeSound() {
        cout << "The cat meows" << endl;
    }
};

int main() {
    Animal* animal;
    Dog dog;
    Cat cat;

    // Animal pointer pointing to a Dog object
    animal = &dog;
    animal->makeSound();

    // Animal pointer pointing to a Cat object
    animal = &cat;
    animal->makeSound();

    return 0;
}

```

Polymorphism Multiple Choice

What is the main benefit of polymorphism in object-oriented programming?

Abstraction

Abstraction

Abstraction is a fundamental concept in object-oriented programming (OOP) that allows us to model real-world objects and systems at a higher level of complexity. It involves hiding unnecessary details and focusing on the essential characteristics of an object or system.

In C++, abstraction is achieved through the use of abstract classes. An abstract class is a class that cannot be instantiated and serves as a blueprint for other classes. It contains pure virtual functions, which are functions with no implementation in the abstract class.

// Abstract class

class Shape {
public:
    // Pure virtual function
    virtual void draw() = 0;
};

The Shape class is an example of an abstract class in C++. It contains a pure virtual function draw(), which is a function that must be overridden in derived classes. This allows for the creation of different shapes, such as circles and rectangles, that each have their own way of being drawn.

// Derived class

class Circle : public Shape {
public:
    void draw() {
        cout << "Drawing a circle" << endl;
    }
};

// Derived class

class Rectangle : public Shape {
public:
    void draw() {
        cout << "Drawing a rectangle" << endl;
    }
};

The Circle and Rectangle classes are derived classes that inherit from the Shape class. They provide the implementation for the draw() function specific to their shape. This allows for the flexibility to create different shapes that can be treated as Shape objects.

int main() {
    Shape* shape1;
    Shape* shape2;

    Circle circle;
    Rectangle rectangle;

    shape1 = &circle;
    shape2 = &rectangle;

    shape1->draw(); // Output: Drawing a circle
    shape2->draw(); // Output: Drawing a rectangle

    return 0;
}

In the main() function, we create objects of the derived classes Circle and Rectangle and assign them to pointers of the base class type Shape. We can then call the draw() function on these pointers, and the appropriate implementation specific to each shape will be invoked.

Abstraction allows us to manage complexity, minimize duplication of code, and promote code flexibility. By focusing on the essential characteristics and hiding unnecessary details, abstraction enhances code readability and maintainability.

```c++
#include <iostream>
using namespace std;

// Abstract class

class Shape {
public:
    // Pure virtual function
    virtual void draw() = 0;
};

// Derived class

class Circle : public Shape {
public:
    void draw() {
        cout << "Drawing a circle" << endl;
    }
};

// Derived class

class Rectangle : public Shape {
public:
    void draw() {
        cout << "Drawing a rectangle" << endl;
    }
};

int main() {
    Shape* shape1;
    Shape* shape2;

    Circle circle;
    Rectangle rectangle;

    shape1 = &circle;
    shape2 = &rectangle;

    shape1->draw(); // Output: Drawing a circle
    shape2->draw(); // Output: Drawing a rectangle

    return 0;
}
```

Abstraction Multiple Choice

Which of the following statements about abstraction in object-oriented programming (OOP) is true?

Encapsulation

Encapsulation

Encapsulation is one of the key principles of object-oriented programming (OOP) that focuses on hiding internal implementation details of a class and providing controlled access to the class's members. By encapsulating data and methods together, encapsulation helps create objects that are self-contained and modular.

In C++, encapsulation is achieved by using access specifiers to control the visibility of class members. The three access specifiers in C++ are:

  • public: Class members declared as public are accessible from any part of the program.
  • private: Class members declared as private are only accessible within the class itself.
  • protected: Class members declared as protected are accessible within the class and its derived classes.

By default, class members are private if no access specifier is specified.

Let's take a look at an example that demonstrates encapsulation in C++:

#include <iostream>
using namespace std;

// Encapsulated class

class Player {
private:
    string name;
    int age;

public:
    void setName(string playerName) {
        name = playerName;
    }

    void setAge(int playerAge) {
        age = playerAge;
    }

    string getName() {
        return name;
    }

    int getAge() {
        return age;
    }
};

int main() {
    Player player;
    player.setName("John Doe");
    player.setAge(25);

    cout << "Player Name: " << player.getName() << endl;
    cout << "Player Age: " << player.getAge() << endl;

    return 0;
}

In this example, we have a class called Player that encapsulates the name and age data members and provides public member functions to set and get their values. The setName and setAge functions are used to set the values of the private members, and the getName and getAge functions are used to retrieve their values.

By encapsulating the data members and providing controlled access through member functions, we ensure that the internal details of the Player class are hidden from outside code. The main function demonstrates how the encapsulated class can be used to create a Player object and access its data through the public member functions.

Encapsulation enhances the security, reliability, and maintainability of code by preventing direct access to internal data and providing a consistent interface for interacting with objects. It also allows for data validation and error checking within the encapsulated class, ensuring that the data remains in a valid state.

```c++
#include <iostream>
using namespace std;

// Encapsulated class

class Player {
private:
    string name;
    int age;

public:
    void setName(string playerName) {
        name = playerName;
    }

    void setAge(int playerAge) {
        age = playerAge;
    }

    string getName() {
        return name;
    }

    int getAge() {
        return age;
    }
};

int main() {
    Player player;
    player.setName("John Doe");
    player.setAge(25);

    cout << "Player Name: " << player.getName() << endl;
    cout << "Player Age: " << player.getAge() << endl;

    return 0;
}

```

Encapsulation Multiple Choice

What is the purpose of encapsulation in object-oriented programming (OOP)?

Generating Complete

Generating complete for this lesson!

Open interactive view →