Przejdź do głównej zawartości

Methods

This lesson will show you how to make use of functions inside a structure creating so-called methods.

Motivation

In programming, objects from real life are often mirrored, for example when creating a racing game 🏎 we will want to have vehicles that are defined by their

  • traits, such as:
    • brand
    • model 🚘
    • max. speed 🚀
  • behaviour, e.g:
    • acceleration 💨
    • braking 🛑

This way of describing objects, separating features and behaviors, is very common. In the lesson on structures we learned how to contain different information about objects within a single type that we created ourselves. By doing so, we described its traits. Now we're going to move on to methods that will allow us to "teach" the object to perform a specific task - that is, to define its behaviour.

Introduction

For the purposes of this lesson, let's create a structure that contains the following features of a car:

struct Car
{
// car information
std::string brand;
std::string model;
int year_of_production;

// movement
float top_speed = 200; // (km/h)
float acceleration = 50; // (km/h per second)
float speed = 0; // current one (km/h)
};

Inside the main function, let's create an object of this structure:

// prism-push-types:Car
int main()
{
Car car;
car.brand = "Ford";
car.model = "Focus";
car.year_of_production = 2010;

}

Now we will move on to how to make it (car) work.

Creating and using methods

Inside the Car structure, at its end, let's put a function, named accelerate, which will increase the speed by the acceleration value of the acceleration:

struct Car
{
// ...
float acceleration = 50;
float speed = 0;
// ...

// increases the speed
void accelerate()
{
speed += acceleration;
}
};
Definition

Methods are functions that are members of a structure (or a class - more on that later in the course). They operate on other structure members and/or provide some functionality for instances of it.

Now we can call accelerate on an object, like this:

Calling the accelerate()
// prism-push-types:Car
// ...

int main()
{
Car car;
// initial values...

// calling for the first time
car.accelerate();
std::cout << "Current speed: " << car.speed << " km/h\n";
// calling for the second time
car.accelerate();
std::cout << "Current speed: " << car.speed << " km/h\n";
}
Result
Current speed: 50 km/h
Current speed: 100 km/h

We use the dot operator (car.accelerate) to access the method we want to call and then inside the parentheses() we pass any required arguments as necessary.

Calling a method
object.method_name(arguments);
Calling a function
function_name(arguments);

Differences between functions and methods

Most methods could be rewritten as regular free functions (outside of any structure). The accelerate method we created above could be rewritten as a function:

// prism-push-types:Car
void accelerate(Car& car)
{
car.speed += car.acceleration;
}

and called like this:

// prism-push-types:Car
Car car;
// initial values...

// calling for the first time
accelerate(car);
std::cout << "Current speed: " << car.speed << " km/h\n";
// calling for the second time
accelerate(car);
std::cout << "Current speed: " << car.speed << " km/h\n";
Zobacz pełen kod
// prism-push-types:Car
#include <iostream>

struct Car
{
// car information
std::string brand;
std::string model;
int year_of_production;

// movement
float top_speed = 200; // (km/h)
float acceleration = 50; // (km/h per second)
float speed = 0; // current one (km/h)
};

void accelerate(Car& car)
{
car.speed += car.acceleration;
}

int main()
{

Car car;
car.brand = "Ford";
car.model = "Mustang";
car.year_of_production = 1969;
car.top_speed = 250;
car.acceleration = 60;
// initial values...

// calling for the first time
accelerate(car);
std::cout << "Current speed: " << car.speed << " km/h\n";

// calling for the second time
accelerate(car);
std::cout << "Current speed: " << car.speed << " km/h\n";
}

As you can see, the main difference is that we need to pass the object as an argument when calling a function, but we do not need to do this for a method.

Definition order

Inside a structure, methods need not be defined before declaring a variable or another method, which also belongs to this structure:

Note the order in which the methods are defined: limit_speed was used in accelerate, even though its definition is below. Similarly, the speed and acceleration fields have been used before their declaration, because it is in the code under this usage. This is allowed within the structure.

struct Car
{
// function that increases the speed
void accelerate()
{
speed += acceleration;
limit_speed();
}

void limit_speed() {
if (speed > top_speed)
speed = top_speed;
}

// class data members
float top_speed = 200;
float acceleration = 50;
float speed = 0;
// the rest...
};

Declaration and definition

As with functions, we can separate the method declaration and definition. This way we are able to move their definitions outside of the structure body:

struct Car
{
// class data members
float top_speed = 200;
float acceleration = 50;
float speed = 0;
// the rest...

// Methods declarations:
void limit_speed();
void accelerate();
};

void Car::limit_speed()
{
if (speed > top_speed)
speed = top_speed;
}

void Car::accelerate()
{
speed += acceleration;
limit_speed();
}

Note that in this case, we precede the method name with the structure name Car, and a double colon ::, the so-called scope resolution operator.

Definition outside the structure body scheme
// prism-push-types:type
type StructureName::method_name(parameters)
{
// ...
}

One of the advantages of this notation is the ability to separate the interface of the structure from its implementation. This way, once you've implemented methods, each time you look at the structure, you will only see the set of variable and method names that you will use, without getting distracted by the implementation details.

This notation is also crucial when splitting the code into multiple files - we'll tell about it further on in the course.

Examples

important

This section requires improvement. You can help by editing this doc page.

Potential errors

important

This section requires improvement. You can help by editing this doc page.

Methods

This lesson will show you how to make use of functions inside a structure creating so-called methods.

Motivation

In programming, objects from real life are often mirrored, for example when creating a racing game 🏎 we will want to have vehicles that are defined by their

  • traits, such as:
    • brand
    • model 🚘
    • max. speed 🚀
  • behaviour, e.g:
    • acceleration 💨
    • braking 🛑

This way of describing objects, separating features and behaviors, is very common. In the lesson on structures we learned how to contain different information about objects within a single type that we created ourselves. By doing so, we described its traits. Now we're going to move on to methods that will allow us to "teach" the object to perform a specific task - that is, to define its behaviour.

Introduction

For the purposes of this lesson, let's create a structure that contains the following features of a car:

struct Car
{
// car information
std::string brand;
std::string model;
int year_of_production;

// movement
float top_speed = 200; // (km/h)
float acceleration = 50; // (km/h per second)
float speed = 0; // current one (km/h)
};

Inside the main function, let's create an object of this structure:

// prism-push-types:Car
int main()
{
Car car;
car.brand = "Ford";
car.model = "Focus";
car.year_of_production = 2010;

}

Now we will move on to how to make it (car) work.

Creating and using methods

Inside the Car structure, at its end, let's put a function, named accelerate, which will increase the speed by the acceleration value of the acceleration:

struct Car
{
// ...
float acceleration = 50;
float speed = 0;
// ...

// increases the speed
void accelerate()
{
speed += acceleration;
}
};
Definition

Methods are functions that are members of a structure (or a class - more on that later in the course). They operate on other structure members and/or provide some functionality for instances of it.

Now we can call accelerate on an object, like this:

Calling the accelerate()
// prism-push-types:Car
// ...

int main()
{
Car car;
// initial values...

// calling for the first time
car.accelerate();
std::cout << "Current speed: " << car.speed << " km/h\n";
// calling for the second time
car.accelerate();
std::cout << "Current speed: " << car.speed << " km/h\n";
}
Result
Current speed: 50 km/h
Current speed: 100 km/h

We use the dot operator (car.accelerate) to access the method we want to call and then inside the parentheses() we pass any required arguments as necessary.

Calling a method
object.method_name(arguments);
Calling a function
function_name(arguments);

Differences between functions and methods

Most methods could be rewritten as regular free functions (outside of any structure). The accelerate method we created above could be rewritten as a function:

// prism-push-types:Car
void accelerate(Car& car)
{
car.speed += car.acceleration;
}

and called like this:

// prism-push-types:Car
Car car;
// initial values...

// calling for the first time
accelerate(car);
std::cout << "Current speed: " << car.speed << " km/h\n";
// calling for the second time
accelerate(car);
std::cout << "Current speed: " << car.speed << " km/h\n";
Zobacz pełen kod
// prism-push-types:Car
#include <iostream>

struct Car
{
// car information
std::string brand;
std::string model;
int year_of_production;

// movement
float top_speed = 200; // (km/h)
float acceleration = 50; // (km/h per second)
float speed = 0; // current one (km/h)
};

void accelerate(Car& car)
{
car.speed += car.acceleration;
}

int main()
{

Car car;
car.brand = "Ford";
car.model = "Mustang";
car.year_of_production = 1969;
car.top_speed = 250;
car.acceleration = 60;
// initial values...

// calling for the first time
accelerate(car);
std::cout << "Current speed: " << car.speed << " km/h\n";

// calling for the second time
accelerate(car);
std::cout << "Current speed: " << car.speed << " km/h\n";
}

As you can see, the main difference is that we need to pass the object as an argument when calling a function, but we do not need to do this for a method.

Definition order

Inside a structure, methods need not be defined before declaring a variable or another method, which also belongs to this structure:

Note the order in which the methods are defined: limit_speed was used in accelerate, even though its definition is below. Similarly, the speed and acceleration fields have been used before their declaration, because it is in the code under this usage. This is allowed within the structure.

struct Car
{
// function that increases the speed
void accelerate()
{
speed += acceleration;
limit_speed();
}

void limit_speed() {
if (speed > top_speed)
speed = top_speed;
}

// class data members
float top_speed = 200;
float acceleration = 50;
float speed = 0;
// the rest...
};

Declaration and definition

As with functions, we can separate the method declaration and definition. This way we are able to move their definitions outside of the structure body:

struct Car
{
// class data members
float top_speed = 200;
float acceleration = 50;
float speed = 0;
// the rest...

// Methods declarations:
void limit_speed();
void accelerate();
};

void Car::limit_speed()
{
if (speed > top_speed)
speed = top_speed;
}

void Car::accelerate()
{
speed += acceleration;
limit_speed();
}

Note that in this case, we precede the method name with the structure name Car, and a double colon ::, the so-called scope resolution operator.

Definition outside the structure body scheme
// prism-push-types:type
type StructureName::method_name(parameters)
{
// ...
}

One of the advantages of this notation is the ability to separate the interface of the structure from its implementation. This way, once you've implemented methods, each time you look at the structure, you will only see the set of variable and method names that you will use, without getting distracted by the implementation details.

This notation is also crucial when splitting the code into multiple files - we'll tell about it further on in the course.

Examples

important

This section requires improvement. You can help by editing this doc page.

Potential errors

important

This section requires improvement. You can help by editing this doc page.