Structs and your first class

Introduction

Keeping a student's name in one variable and their marks in another soon gets out of hand. Structs group data under one name, and classes go further by putting rules around that data. This lesson gives you the essentials, and StepVioz's Object-Oriented Programming course covers design in depth.

How it works

Structs group values. Each member is reached with a dot. Assigning one struct to another copies all of its members:

#include <iostream>
#include <string>
using namespace std;

struct Student {
    string name;
    int marks;
};

int main() {
    Student a{"Mitu", 82};
    Student b = a;
    b.marks = 90;
    cout << a.name << " " << a.marks << endl;
    cout << b.name << " " << b.marks << endl;
    return 0;
}
Open in compiler

Classes look the same, but their members are private by default. Private members can be used only by the class's own methods, so that all changes must go through code that can check them.

Methods are functions inside a class. A method marked const promises not to change the object, and can be called on const objects.

Constructors have the same name as the class and no return type. They run when an object is created. The part after the colon is an initialiser list, which sets members directly:

Counter(int start) : value(start) {}

struct or class? The only difference in the language is the default visibility. By convention, use struct for plain groups of data and class when there are rules to protect.

Syntax

class Account {
    int balance;
public:
    Account() : balance(0) {}
    void deposit(int amount) { balance += amount; }
    int get() const { return balance; }
};

Example

#include <iostream>
using namespace std;

class Counter {
    int value;

public:
    Counter(int start) : value(start) {}

    void add() {
        value++;
    }

    int get() const {
        return value;
    }
};

int main() {
    Counter c(5);
    c.add();
    c.add();
    cout << c.get() << endl;
    return 0;
}
Open in compiler

Line by line

  1. value is private, because members of a class are private by default.
  2. The constructor sets value from its argument.
  3. add changes the object, and get is const because it only reads.
  4. Counter c(5); creates an object and runs the constructor.
  5. After two calls to add, get returns 7.

Expected result

7

In the real world

std::string and std::vector are classes whose private details you never touch, which is why they are so hard to misuse. Well-designed classes make wrong use difficult.

Common mistakes

  • Forgetting the semicolon after the closing brace of a class.
  • Trying to read a private member from outside the class.
  • Leaving a member without a value, because no constructor set it.
  • Forgetting const on methods that only read.

Best practices

  • Keep data private, and expose only what callers need.
  • Set every member in the constructor.
  • Pass objects by const& unless they must change.

Summary

Structs group data, and classes add privacy and methods. Constructors create valid objects, and const methods promise only to read. Private data can only be changed by the class's own code.

Quick check

1. What is the default visibility of class members?
2. When does a constructor run?
3. What does Student b = a; do for a struct?
4. What does const after a method mean?

Key takeaways

  • In a struct members are public by default, and in a class they are private.
  • A constructor makes sure every object starts valid.
  • Keep data private, and offer methods that keep it correct.

Practice problems for this lesson

My notes

Write down what you want to remember from this lesson. Notes are saved on this device as you type, and appear on your dashboard.