Objects and Classes in C++
On this page
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
A simple class
class Point {
int x; // an instance variable
int y;
// above: members are private by default
public:
// below: members are public
// below are all methods
Point(); // default constructor
Point(int x, int y);
void setX(int x); // mutator/setter
int getX() { // accessor/getter, inline definition
return x;
}
void setY(int y); // mutator/setter
int getY();
}; // end with ;
// out-of-line definition after
Point::Point(): x(0), y(0) {}
Point::Point(int x, int y): x(x), y(y) {}
void Point::setX(int x) {
this->x = x;
}
void Point::setY(int y) {
this->y = y;
}
int 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
- as sections (different from Java)
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) thispointer as a pointer pointing to the current object in method definition- use of
->operator
- use of
- Scope resolution 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
class MyClass { int size; public: void print() const { cout << "Hello!\n"; } int size() const { return size; } };
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
// 1. in-class initializer, always effective
class MyClass {
private:
int value = 10; // <-- here
public:
MyClass()=default; // doing nothing
};
// 2. constructor member initializer list, only affect one constructor
class MyClass {
private:
int value;
public:
MyClass(): value(10) {} // <-- here
};
// 3. Naive assignment
class MyClass {
private:
int value;
public:
MyClass() {
value = 10; // <-- here
}
};
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):
int myFunction(MyClass obj); int main() { // as a parameter, MyClass(10) is a temp object cout << myFunction(MyClass(10)) << endl; // assign to another object // copy constructor or copy assignment operator will be triggered // MyClass(10) is a temp object MyClass objArray[10]; // object array, default constructor triggered objArray[0] = MyClass(10); // copy assignment operator triggered }
-
-
.member accessing operator:MyClass obj; cout << obj.getValue() << endl; -
->member accessing operator from pointer:// pointer to class MyClass *objPtr; objPtr = new MyClass; // objPtr->getValue() is same as (*objPtr).getValue() cout << objPtr->getValue() << endl; -
::Domain resolution operator:// Name space std::string myString; // Class method out-of-line definition void MyClass::print() { cout << "value: " << this->value << endl; } // Class static members // static int square(int value) { return value * value}; MyClass obj1; cout << obj1.square(5) << endl; // use object to access cout << 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.
class User {
-string id
-string name
+User()
+User(string id, string name)
+string getName()
+string getID()
}
Static Members (FYI)
- static keyword
- one per class
- global life span
- stored in the
staticmemory region - instance variable
-
data shared among objects
-
can only be initialized outside of the class declaration:
// my-class.hpp class MyClass { private: static int count; // NEVER initialize here! public: // ... }; // my-class.cpp // omit the static keyword int 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
my-class.hpp
#ifndef MY_CLASS_HPP
#define MY_CLASS_HPP
class MyClass {
private: // optional, anything not in the public section is private
int value;
void doubleVal(); // private helper
public:
MyClass(); // default constructor
MyClass(int value); // parameterized constructor
int getValue() const; // accessor/getter
void setValue(int value); // mutator/setter
int getDoubledValue(); // general public method
}; // WARNING: must have ; here
#endif // MY_CLASS_HPP
my-class.cpp
#include "my-class.hpp"
void MyClass::doubleVal() {
value *= 2;
}
int MyClass::getDoubledValue() {
doubleVal();
return value;
}
// default constructor
// with initializer list to set value to 0
MyClass::MyClass(): value(0) {}
// parameterized constructor
// using initializer list
// MyClass::MyClass(int value): value(value) {}
// not using initializer list
MyClass::MyClass(int value) {
// this->value refers to the instance variable
// must add this-> when names conflict
this->value = value;
}
int MyClass::getValue() const {
return value;
}
// cannot use the initializer list because this is not a constructor
void MyClass::setValue(int value) {
this->value = value;
}
main.cpp
// pay attention to the order
// user header first
// system header last
#include "my-class.hpp"
#include <iostream>
using namespace std;
int main() {
// trigger the default constructor
MyClass obj1;
cout << obj1.getValue() << endl; // get 0
// trigger the parameterized constructor
MyClass obj2(10);
// alternatives
// MyClass obj2{10}; // since c++11, preferred
// MyClass obj2 = 10; // trigger the parameterized constructor
cout << obj2.getValue() << endl; // get 10
MyClass *ptr1;
ptr1 = new MyClass(15); // use new to call the constructor
cout << ptr1->getValue() << endl; // get 15
cout << (*ptr1).getValue() << endl; // get 15
}
makefile
main: main.o my-class.o
g++ -o $@ $^
main.o: main.cpp my-class.hpp
g++ -std=c++14 -Wall -c -o $@ $<
my-class.o: my-class.cpp my-class.hpp
g++ -std=c++14 -Wall -c -o $@ $<
clean:
rm -f *.o main