CCC 5: Objects - TEAM1771/Crash-Course GitHub Wiki

Classes and Structures

So far, we have explored the basic variable types (int, double, char, bool, etc.), but you have probably also noticed different variable types thrown in (units::meters_per_second_t, units::degree_t, std::string, etc.).

These are called objects, and can be either classes or structures.

  • An object is essentially a way of creating a custom variable, including data and logic

A class or structure is a made in a similar way to a namespace.

  • You begin by typing class or struct, followed by the name of the class, and enclose the contents in brackets.
  • Unlike namespaces, classes must end in a semicolon.
class Robot
{
    
};
struct Robot
{
    
};

A class or struct can contain variables (aka members), as well as functions (sometimes called methods when used in a class/struct).

Constructor

One function/method which all classes and structures have (whether or not you choose to declare it) is called the constructor.

  • This does exactly what it says: constructs the object.
  • This function is run any time you create an instance of the class or struct (as a variable).
  • It has no return type, and is called the same name as the object.
  • It can also take parameters if needed.
class Robot
{
    int ID;

    public: 
    Robot(int robots_ID)
    {
        ID = robots_ID;
        std::cout << ID;
    }
};

Robot robot_1 = Robot(1); // ID = 1, prints 1
Robot robot_2 = Robot(2); // ID = 2, prints 2
Robot robot_3{3}; // This is an alternative way of intializing a variable
                  // ID = 3, prints 3

Extra Resources

If you're confused or just want to learn more, check out these resources. I especially recommend the video series.

W3Schools, Geeks4Geeks, Microsoft Docs, The Cherno video

Visibility and Accessibility

By default, any variables or functions declared in a class are private.

**This means they can only be accessed by other functions in the class. **

However, anything following public: will be able to seen, modified, and used in other code.

For structures, it is the other way around: everything is public by default, and you must use private: to hide a variable or function.

Because of this difference, structures are usually used as a way of holding many public variables, while classes are typically used more often when logic and hidden variables are involved. However, both can be used interchangeably. Everything that follows in this guide applies to both classes and structs.

Class functions and variables can be accessed by using the name of an instance of a class, followed by a . and the name of the variable or function.

class Robot
{
    int ID;

    public: 
    
    std::string name;

    Robot(int robots_ID, std::string robots_name)
    {
        ID = robots_ID;
        std::cout << ID;

        name = robots_name;
    }

    void setNewName(std::string new_name)
    {
        name = new_name;
    }

    void setNewID(int new_ID)
    {
        ID = new_ID;
    }
};

int main()
{
    Robot robot_1 = Robot(1, "Robosaurus"); // ID = 1, prints 1

    robot_1.ID = 2; // This won't work because "ID" is a private variable.

    robot_1.setNewID(2); // This is fine because "setNewID" is a public function.

    robot_1.name = "O-Bob"; // This works because "name" is a public variable

    robot_1.setNewName("MOMENTARY"); // This is also public.
}

Extra Resources

For more on visibility, watch this video from The Cherno

Static in Objects

The keyword static in C++ has 4 uses. Right now we'll only cover the use of static specifically in classes/structs, but we'll talk more about it in chapter 7.

Static can be used in classes to create static variables or functions, and it is used by typing static before the variable or function declaration.

  • Static variables in a class: Shared between instances of a class and can be accessed without creating an instance (if public)
  • Static class functions: Can be accessed/called without creating an instance (if public)

Static variables and functions can be accessed outside of an instance by using the name of the class, followed by :: (2 colons) (the same way you should access something in a namespace).

class Robot
{
    int ID;

    public: 
    
    std::string name;

    static int num_of_robots = 0;

    Robot(int robots_ID, std::string robots_name)
    {
        ID = robots_ID;
        std::cout << ID;

        name = robots_name;

        num_of_robots++; // Same as num_of_robots = num_of_robots + 1;
    }
};

Robot robosaurus{0, "Robosaurus"};
Robot OBob{1, "O-Bob"};

std::cout << Robot::num_of_robots; // Outputs 2
std::cout << robosaurus.num_of_robots; // Outputs 2
std::cout << OBOB.num_of_robots; // Outputs 2

OBOB.num_of_robots = 3;

std::cout << robosaurus.num_of_robots; // Outputs 3

Static variables are created when the program first runs and are then shared between every instance of that class. This is very useful for keeping a shared number or counting the number of instances of a class. Static variables can also be private:

Class Demo
{
    static int private_var = 0;

    public:

    void setPrivateVar(int new_val)
    {
        private_var = new_val;
    }

    int getPrivateVar()
    {
        return private_var;
    }
};

Demo demo_1 = Demo();
Demo demo_2{}; // equivalent to the line above

demo_1.setPrivateVar(3);
std::cout << demo_2.getPrivateVar(); // Outputs 3

The code above is an example of a common OOP format: encapsulation (object-oriented programming is a style of programming implemented in many programming languages including Java and C++). This involves making a private variable which can be accessed only through functions (we do not use this format, but it is useful to know if you plan on taking AP CSA).

Static functions are useful if you have some logic that can be recycled throughout all the instances of your class.

  • They can also be used to access a private static variable outside an instance.
  • Static functions can only access static variables (because you wouldn't be able to access a variable that is specific to an instance of a class when calling the function from outside an instance).
Class Demo
{
    static int private_var = 0;

    public:

    static void setPrivateVar(int new_val)
    {
        private_var = new_val;
    }

    static int getPrivateVar()
    {
        return private_var;
    }

    static convert(int a)
    {
        // Does some sort of conversion which is needed in all instances of your class
        return a;
    }
};

Demo demo_1 = Demo();
Demo demo_2{};

Demo::setPrivateVar(3);

std::cout << demo_2.getPrivateVar(); // Outputs 3

Demo::getPrivateVar(); // Also outputs 3

Demo::convert(3);

demo_1.convert(3); // Same result as above

Extra Resources

More reading from Microsoft Documentation and a video from The Cherno.

Inheritance, Polymorphism, and Abstract objects

If you have extra time, I suggest learning about the concepts of inheritance, polymorphism, and abstract classes, but these are not required for writing robot code.