C++ Classes
We already know about structs which bring together several
variables that describe a "thing." However, to implement functions, we'd have to pass the
struct by value.
In the object oriented way, we prefer to have related functionality (print_rectangle,
area for a rectangle class) be part of the object (the struct)
What is a class
- A class definition is like a blueprint defining a type.
- Objects of that type are created from that blueprint
- Once we define a class, we have one blueprint from which we can create 0 or more objects.
- Each of the objects is an instance of the class and has its own copies of all instance variables.
Writing C++ Classes
- Class definition goes in a
.hfile. - Functions can be declared and defined inside
class {...}. - Only define member functions inside the class definition if it's very short. This is called
"in-lining" the function definition. Otherwise, put a prototype in the class definition and define the
member function in a
.cppfile.- You'll need to qualify the function with the class scope such as
Classname::function(){}in the.cppfile. - Do not try to initial class fields immediately when they are declared. E.g.,
double width = 10;because this is allowed for static fields.
- You'll need to qualify the function with the class scope such as
const modifier
void print() const {
...
}
- The use of
constas modifier in method header indicates that the function will not modify any member fields. constcan be used for member fields too.
Examples
In-lining example:
// rectangle.h
#ifndef RECTANGLE_H
#define RECTANGE_H
class Rectangle {
...
double area() const {
// in-lining
return width*height;
}
...
};
#endif //RECTANGLE_H
Defining a function outside class:
// rectangle.h
#ifndef RECTANGLE_H
#define RECTANGLE_H
class Rectangle {
...
double area() const;
...
}
#endif //RECTANGLE_H
// rectangle.cpp
#include "rectangle.h"
double Rectangle::area() const {
//define outside class
return width * height;
}
class2.cpp:
#include <iostream>
class Rectangle {
public:
double width;
double height;
void print() const {
std::cout << "width=" << width << ", height=" << height << std::endl;
}
double area() const {
return width*height;
}
};
int main() {
Rectangle r = {30.0, 40.0};
r.print();
std::cout << "area=" << r.area() << std;;endl;
return 0;
}
- Notice that the member functions doesn't need to pass in the parameters since they can directly access the fields because they are in the same class.
Protection
Fields and member functions can be public, private, or protected.
- A
publicfield or member function can be accessed freely by any code with access to the class definition (code that includes the.hfile). - A
privatefield or member function can be accessed from other member functions in the class, but not by a user of the class.
- Base-class members markedprivatecannot be accessed from member functions defined in the derived class. (They are still there, only derived class member functions can't use them withoutpublicorprotectedaccessor or mutator functions)
We usepublic:andprivate:to divide class definition into sections according to whether members arepublicorprivate.
privateis default.
How to section:
class Rectangle {
public:
...
double area() const {
//definition inside class
return width * height;
}
...
private:
double width, height;
};
\
- A
protectedfield or member functions can be accessed from member functions of their class and from functions defined in derived classes.- Based class members marked
publicorprotectedcan be accessed from member functions defined in the derived class
- Based class members marked
this pointer
When another member function has a parameter with the same name as the instance variable it is supposed to
initialize, the local variable (parameter) will hide the instance variable.
this is a pointer to the instance variable and can be used to clarify.
this->initalways refers to the instance variableinit.
We don't use this unless necessary in C++, unlike Java, where it is a good style to always
qualify instance members.
Array of Objects
Declaring an array of a class type makes all the objects, calling the default constructor to create each one. Thus, requires the class to have a default constructor.
What if you don't want to have default constructor?
-
List
Use list-initialization to initialize each object in the array.
MyThing s[3] = {{3}, {2}, {4}};
Every value inside will be the engines for the objects.MyThingonly has one member field, so we only provide one value. This is called listing test when we initialize structures by passing in different values. -
use
STLto reserve some element size
int main() {
// empty vector and reserve 10 element size
std::vector<MyThing> s;
s.reserve(10);
// initialization using emplace_back
for (int i = 0; i < 10; ++i) s.emplace_back(i);
}