In this lab, we will introduce the basics of object-oriented programming (OOP) in C++ by exploring the C++ class. Classes are a fundamental concept in C++ that allow you to create your own custom data types, bundling data and functions together into a single unit. We will cover the key components of a class, including members, access specifiers, constructors, and member functions.
§1 Classes #
A class in C++ is a user-defined type that bundles data and the operations that can be performed on that data.
Unlike structs, every member member is private by default, so outside code cannot tamper with the object’s internal state unless explicitly exposed. This encapsulation is the bedrock of object-oriented design.
A class declaration has the following format:
class MyClass {
public:
// Public members (accessible from outside the class)
int myPublicVar;
void myPublicMethod();
private:
// Private members (accessible only from within the class)
// when `public:` is not declared, all class members are implicitly private
int myPrivateVar;
void myPrivateFunction();
};
- The
classkeyword is used to declare a new class. publicandprivateare the “access specifiers” that control the external visibility of the class members.- A
functiondeclared within a class is known as a classmember
§1.1 Public vs. Private Members #
Publicmembers can be accessed from anywhere in the program, including from outside the class. They form the public interface of the class.Privatemembers can only be accessed from within the class itself. They are used to hide the internal implementation details of the class, which is a key aspect of encapsulation.protectedmembers are visible to the class and its derived classes. (used with Inheritance, which we will cover in a later lab).
By default, all members of a class are private unless you specify otherwise.
§1.2 Member functions #
Member functions are functions that are part of a class. They can access both public and private members of the class. Member functions are defined like regular functions, but are associated with a class.
Example: Defining a Simple Class
#include <iostream>
// define the "Dog" class
class Dog {
public:
// Public member function
void bark() {
std::cout << "Woof!" << std::endl;
}
};
int main() {
Dog myDog; // Create an instance of the Dog class, this is known as an "object"
myDog.bark(); // Call the bark() member function on the Dog object
}
In this example, the Dog class has a public member function bark(), which can be called on an instance of the Dog class by using the dot notation.
§1.3 Constructors #
A constructor is a special member function that is automatically called when an object of the class is created. It is used to initialize the object’s data members.
A constructor always has the same name as the class, and does not have a return type.
Example: Declaring and Using a Constructor
#include <iostream>
class Car {
public:
// Constructor
Car(std::string make, std::string model, int year) {
this->make = make; // "this->" is explained in the next section
this->model = model;
this->year = year;
}
void printInfo() {
std::cout << "Make: " << make << ", Model: " << model << ", Year: " << year << std::endl;
}
private:
std::string make;
std::string model;
int year;
};
int main() {
Car myCar("Toyota", "Tundra", 2020); // use constructor to instantiate and populate new "Car" object
myCar.printInfo();
}
In this example, the Car class has a constructor that takes the make, model, and year as arguments and initializes the corresponding data members.
§1.3.1 Constructor types #
C++ offers two equivalent ways to initialize data members inside a constructor:
Assignment inside the body:
class Car {
public:
Car(std::string make, std::string model, int year) {
this->make = make; // assignment
this->model = model;
this->year = year;
}
private:
std::string make, model;
int year;
}
Member-initializer list:
class Car {
public:
// memberinitializer list
Car(std::string make, std::string model, int year)
: make(make), model(model), year(year) {} //direct initialization
private:
std::string make, model;
int year;
}
Both forms are equivalent, which form you use is purely a matter of style.
The member-initializer list is preferred in modern C++ because it avoids the inefficiency of default-constructing and then reassigning members, and it keeps initialization logic with the corresponding data-member declaration.
§1.4
The this Pointer
#
The this pointer is a special pointer that is available to all non-static member functions of a class. It always points to the current object instance. It is often used to distinguish between data members and function parameters with the same name.
In the Car constructor example above, this->make = make; assigns the value of the make parameter to the make data member of the Car object.
this is not available in static member functions, since they do not have a concrete object instance.
struct S {
int v;
void f(int v) {
this->v = v;
} // Valid, the `v` member of the class is set to the value of parameter `v`
static void g() {
/*this->v = 0;*/
} // ERROR: `this` is not valid in static members
};
§2 Questions #
- What is the main difference between a
structand aclassin C++?
- What is the purpose of a constructor in a C++ class?
- What is the
thispointer, and when is it used?
- What are access specifiers, and why are they important in object-oriented programming?
- In this example, is x
publicorprivate? Explain why.
class Gadget {
int x;
};
- In this example, is y
publicorprivate? Explain why.
struct Gadget {
int y;
};
- Write the full header (no body) for a constructor of a class
Pointthat takes two doubles as parameters.
- What is the name of the object created by this code snippet?
Car c("Honda", "Civic", 2017);
- Complete this class definition to print “woof” when
bark()is called, then complete themain()function.
class Dog {
void bark();
};
int main() {
// write code that will create a Dog instance and then use it to print "woof"
}
- In
Person::setAge(int age) { this->age = age; }, what would break if you removedthis->and changed the parameter name toainstead? explain why.
- Which of these can use the
thispointer: a) a static member function b) a non-static member function c) both
- Explain briefly (1-2 sentences): why set data members private instead of public?
- How must this code change to be able to create one
Car c("Tesla", "Model 3", 2022)and print only itsyear?
#include <iostream>
class Car {
public:
// Constructor
Car(std::string make, std::string model, int year)
: make(make), model(model), year(year) {}
void printInfo() {
std::cout << "Make: " << make
<< ", Model: " << model
<< ", Year: " << year << std::endl;
}
private:
std::string make;
std::string model;
int year;
};
int main() {
}