Objects and Classes in C++¶
Concepts¶
General Object-oriented Programming¶
- object:
a collection of coherent states and behaviors
- class:
a template of a group of similar objects
- state:
data, property, attribute, member variable
- behavior:
method, member function
map to C++ concepts¶
- class:
a type
- object:
a variable (instance) of a class type
- state:
an instance variable
- behavior:
a method
1class Point {
2 int x; // an instance variable
3 int y;
4 // above: members are private by default
5 public:
6 // below: members are public
7 // below are all methods
8 Point(); // default constructor
9 Point(int x, int y);
10 void setX(int x); // mutator/setter
11 int getX() { // accessor/getter, inline definition
12 return x;
13 }
14 void setY(int y); // mutator/setter
15 int getY();
16}; // end with ;
17
18// out-of-line definition after
19Point::Point(): x(0), y(0) {}
20
21Point::Point(int x, int y): x(x), y(y) {}
22
23void Point::setX(int x) {
24 this->x = x;
25}
26
27void Point::setY(int y) {
28 this->y = y;
29}
30
31int Point::getY() { return y;}
Class Declaration¶
class keyword (or struct keyword)
Usually in header file
Semicolon after }
Members
data member - instance variable
function member - method (member function)
visibility (access specifier)
as sections (different from Java)
public: accessible anywhere
private: accessible only within objects of the same class
protected, etc.: not discussed in the courses
default
private in class
public in struct
always prefer information hiding
make private if possible
almost all instance variables are private
only methods to be used out of the class should be public
Methods¶
Inline definitions: in the class declaration
Out-of-line definitions: out of the class declaration
Scope resolution operator
::
to specify the owner of the method (the class)this
pointer as a pointer pointing to the current object in method definitionuse of
->
operator
Types of methods
- Constructor¶
The methods to be triggered when the object is created. Same name as the class. No return type (because they always return the new object). May be overloaded.
- Destructor¶
The method to be triggered when the object is destroyed. No parameter. One per class.
- Accessor¶
A.k.a getter. A simple method to return the value of an instance variable. Should be const methods in most cases.
- Mutator¶
A.k.a setter. Takes one const parameter and set an instance variable to the value passed in.
- Private helper¶
A general name of all private methods as they are usually used to help other methods.
Constructor
No return type
Initializer list (read this)
constructor only syntax
initializes values of instance variables
Default constructor
no parameter
define initial value
to trigger
MyClass obj; MyClass obj(); MyClass obj{}; MyClass obj[10]; // every element created using the default constructor
Parameterized constructor
Duplication constructors (further discussed here)
copy constructor
move constructor
Const methods: methods that cannot not modify any instance variable
any other method called within a const method must be const too
1class MyClass { 2 int size; 3 public: 4 void print() const { 5 cout << "Hello!\n"; 6 } 7 int size() const { 8 return size; 9 } 10};
Data Initialization of Non-Static Instance Variable¶
In-class initializer (constructor only syntax, since c++11)
Initializer list in the constructor (preferred)
Assignment in the constructor
Note
Two methods can be mixed. Use the first method for initial values shared among multiple constructors; Use the second method for values that differs among various constructors. When used together, the first will be ignored.
1// 1. in-class initializer, always effective
2class MyClass {
3 private:
4 int value = 10; // <-- here
5 public:
6 MyClass()=default; // doing nothing
7};
8
9// 2. constructor member initializer list, only affect one constructor
10class MyClass {
11 private:
12 int value;
13 public:
14 MyClass(): value(10) {} // <-- here
15};
16
17// 3. Naive assignment
18class MyClass {
19 private:
20 int value;
21 public:
22 MyClass() {
23 value = 10; // <-- here
24 }
25};
Using Class/Object¶
Declare a variable of a class type
Initialization using the constructor:
MyClass myObj1(10); MyClass myObj1 = 10; // same as the above example MyClass myObj1{10}; // since C++11
Disposable object assignment (Class name followed by parenthesis to trigger the constructor):
1int myFunction(MyClass obj); 2 3int main() { 4 // as a parameter, MyClass(10) is a temp object 5 cout << myFunction(MyClass(10)) << endl; 6 7 // assign to another object 8 // copy constructor or copy assignment operator will be triggered 9 // MyClass(10) is a temp object 10 MyClass objArray[10]; // object array, default constructor triggered 11 objArray[0] = MyClass(10); // copy assignment operator triggered 12}
.
member accessing operator:MyClass obj; cout << obj.getValue() << endl;
->
member accessing operator from pointer:1// pointer to class 2MyClass *objPtr; 3objPtr = new MyClass; 4// objPtr->getValue() is same as (*objPtr).getValue() 5cout << objPtr->getValue() << endl;
::
Domain resolution operator:1// Name space 2std::string myString; 3 4// Class method out-of-line definition 5void MyClass::print() { 6 cout << "value: " << this->value << endl; 7} 8 9// Class static members 10// static int square(int value) { return value * value}; 11MyClass obj1; 12cout << obj1.square(5) << endl; // use object to access 13cout << MyClass::square(5) << endl; // use class to access
UML Class Diagrams (FYI)¶
The Unified Modeling Language is a general-purpose modeling language used in software engineering. The class diagram is one type of UML diagram used to model classes and relationships among them in object-oriented programming.
The class diagrams used here is in the PlantUML format. You can check this document for more information.
1class User {
2 -string id
3 -string name
4 +User()
5 +User(string id, string name)
6 +string getName()
7 +string getID()
8 }
Static Members (FYI)¶
static keyword
one per class
global life span
stored in the
static
memory regioninstance variable
data shared among objects
can only be initialized outside of the class declaration:
1// my-class.hpp 2class MyClass { 3private: 4 static int count; // NEVER initialize here! 5public: 6 // ... 7}; 8 9// my-class.cpp 10// omit the static keyword 11int MyClass::count = 10;
method
can not access any instance variable
can access static instance variable
e.g. pure math functions
either
MyClass::method()
orobj.method()
to trigger
Class Example¶
1#ifndef MY_CLASS_HPP
2#define MY_CLASS_HPP
3
4class MyClass {
5 private: // optional, anything not in the public section is private
6 int value;
7 void doubleVal(); // private helper
8 public:
9 MyClass(); // default constructor
10 MyClass(int value); // parameterized constructor
11 int getValue() const; // accessor/getter
12 void setValue(int value); // mutator/setter
13 int getDoubledValue(); // general public method
14}; // WARNING: must have ; here
15
16#endif // MY_CLASS_HPP
1#include "my-class.hpp"
2
3void MyClass::doubleVal() {
4 value *= 2;
5}
6
7int MyClass::getDoubledValue() {
8 doubleVal();
9 return value;
10}
11
12// default constructor
13// with initializer list to set value to 0
14MyClass::MyClass(): value(0) {}
15
16// parameterized constructor
17// using initializer list
18// MyClass::MyClass(int value): value(value) {}
19
20// not using initializer list
21MyClass::MyClass(int value) {
22 // this->value refers to the instance variable
23 // must add this-> when names conflict
24 this->value = value;
25}
26
27int MyClass::getValue() const {
28 return value;
29}
30
31// cannot use the initializer list because this is not a constructor
32void MyClass::setValue(int value) {
33 this->value = value;
34}
1// pay attention to the order
2// user header first
3// system header last
4#include "my-class.hpp"
5#include <iostream>
6
7using namespace std;
8
9int main() {
10 // trigger the default constructor
11 MyClass obj1;
12 cout << obj1.getValue() << endl; // get 0
13
14 // trigger the parameterized constructor
15 MyClass obj2(10);
16 // alternatives
17 // MyClass obj2{10}; // since c++11, preferred
18 // MyClass obj2 = 10; // trigger the parameterized constructor
19 cout << obj2.getValue() << endl; // get 10
20
21 MyClass *ptr1;
22 ptr1 = new MyClass(15); // use new to call the constructor
23 cout << ptr1->getValue() << endl; // get 15
24 cout << (*ptr1).getValue() << endl; // get 15
25}
1main: main.o my-class.o
2 g++ -o $@ $^
3
4main.o: main.cpp my-class.hpp
5 g++ -std=c++14 -Wall -c -o $@ $<
6
7my-class.o: my-class.cpp my-class.hpp
8 g++ -std=c++14 -Wall -c -o $@ $<
9
10clean:
11 rm -f *.o main