wk02_OO_basics


Basics of Object-Oriented Programming

C++ program that demonstrates these concepts in a computational science context. The program will model a particle system with 2D and 3D particles, showcasing class construction, operator overloading, and function overloading.

Resources (C++ Tutorial)

algorithm, array initialization, auto, class, cmath, command line arguments, curly_brackets, encapsulation, friend, function overloading, initializer lists, iostream, namespace, operator overloading, private, protected, public, range-based, sstream, std::cin, std::cout, std::istream, std::ostream, std::runtime_error, struct, throw, vector

Implementation

#include <iostream>
#include <vector>
#include <cmath>

// Vector class to represent both 2D and 3D vectors
class Vector {
public:
    Vector(std::vector<double> components) : components_(components) {}

    Vector operator+(const Vector& other) const {
        if (components_.size() != other.components_.size()) {
            throw std::runtime_error("Vector dimensions do not match");
        }
        std::vector<double> result(components_.size());
        for (size_t i = 0; i < components_.size(); ++i) {
            result[i] = components_[i] + other.components_[i];
        }
        return Vector(result);
    }

    friend std::ostream& operator<<(std::ostream& os, const Vector& v) {
        os << "(";
        for (size_t i = 0; i < v.components_.size(); ++i) {
            os << v.components_[i];
            if (i < v.components_.size() - 1) os << ", ";
        }
        os << ")";
        return os;
    }

    std::vector<double> components_;
};

// Function overloading for vector norm
double norm(const Vector& v) {
    if (v.components_.size() == 2) {
        return std::sqrt(v.components_[0] * v.components_[0] + v.components_[1] * v.components_[1]);
    } else if (v.components_.size() == 3) {
        return std::sqrt(v.components_[0] * v.components_[0] + v.components_[1] * v.components_[1] + v.components_[2] * v.components_[2]);
    } else {
        throw std::runtime_error("Norm function only supports 2D and 3D vectors");
    }
}

// Norm function for 2D vectors
double norm(double x, double y) {
    return std::sqrt(x * x + y * y);
}

// Norm function for 3D vectors
double norm(double x, double y, double z) {
    return std::sqrt(x * x + y * y + z * z);
}

// Norm function for an array (generalized for any dimension)
double norm(const double* components, size_t size) {
    double sum = 0.0;
    for (size_t i = 0; i < size; ++i) {
        sum += components[i] * components[i];
    }
    return std::sqrt(sum);
}

class Particle {
public:
    Particle(double mass, const Vector& position, const Vector& velocity)
        : mass_(mass), position_(position), velocity_(velocity) {
        std::cout << "Particle created at position " << position_ << std::endl;
    }

    ~Particle() {
        std::cout << "Particle destroyed at position " << position_ << std::endl;
    }

    void updatePosition(double time) {
        std::vector<double> displacement(velocity_.components_.size());
        for (size_t i = 0; i < displacement.size(); ++i) {
            displacement[i] = velocity_.components_[i] * time;
        position_ = position_ + Vector(displacement);
    }

    void printState() const {
        std::cout << "Particle - Mass: " << mass_ << ", Position: " << position_
                  << ", Velocity: " << velocity_ << ", Speed: " << norm(velocity_) << std::endl;
    }

private:
    double mass_;
    Vector position_;
    Vector velocity_;
};

int main() {
    // Create a 2D particle
    Particle particle2D(5.0, Vector({0.0, 0.0}), Vector({1.0, 2.0}));
    std::cout << "Initial state of 2D particle:" << std::endl;
    particle2D.printState();

    particle2D.updatePosition(2.0);
    std::cout << "2D particle after 2 seconds:" << std::endl;
    particle2D.printState();

    // Create a 3D particle
    Particle particle3D(10.0, Vector({0.0, 0.0, 0.0}), Vector({1.0, 2.0, 3.0}));
    std::cout << "\nInitial state of 3D particle:" << std::endl;
    particle3D.printState();

    particle3D.updatePosition(2.0);
    std::cout << "3D particle after 2 seconds:" << std::endl;
    particle3D.printState();

    // Demonstrate vector addition
    Vector v1({1.0, 2.0});
    Vector v2({3.0, 4.0});
    Vector v3 = v1 + v2;
    std::cout << "\nVector addition: " << v1 << " + " << v2 << " = " << v3 << std::endl;

    return 0;
}

This program demonstrates the requested elements in a computational science context:

  1. Class, Constructor, and Destructor: The Particle class models a physical entity with properties like position, velocity, and mass. It includes a constructor to initialize these properties and a destructor that prints a message when the particle is destroyed.

  2. Operator Overloading: The Vector class overloads the + operator to add two vectors, which is useful in various computational science applications such as finite element analysis or linear algebra operations.

  3. Function Overloading: The norm function is overloaded to compute the norm (magnitude) of both 2D and 3D vectors using conditional statements inside the function. It uses the vector's size to determine which calculation to perform. Multiple versions of the norm function are provided, distinguished by the number of arguments and the argument types.

  4. Additional Features:

  5. The Vector class is flexible and can represent both 2D and 3D vectors.
  6. The updatePosition method in the Particle class demonstrates how the particle's position changes over time based on its velocity.
  7. The program showcases the use of these classes and functions in the main function, creating and manipulating both 2D and 3D particles.

This code provides a foundation for more complex particle simulations or physical system modeling in computational science. It demonstrates key C++ concepts while maintaining relevance to scientific computing applications.

Related

Previous Page | Course Schedule | Course Content