Structs, Classes, and Arrays Structs A type representation containing a set of heterogeneous members with possibly varying types. struct Student { string name; int id; double tuition; ; Note: Syntactically, a ; is needed at the end of a struct definition. Accessing a member of a struct, you can use the. operator (since members of a struct by default are public. int main() { Student s; s.name = Richert ; s.id = 12345678; s.tuition = 0; cout << Name: << s.name <<, id: << s.id <<, tuition: << s.tuition << endl; return 0; Memory Organization of structs - Members are stored contiguously and space is allocated based on the types of members Student s; cout << sizeof(s.name) <<, << sizeof(s.id) <<, << sizeof(s.tuition) << endl; Padding - Some members, such as chars, may consume more memory than the actual size of the type. - Mainly for performance reasons and how data is fetched. - Depends on the compiler and underlying computer architecture. Classes A class is a representation of a user- defined type. Classes consist of: - An interface: What operations are available when using this class. - An implementation: The definition of how things are done.
Example of a class interface: #include<iostream> using namespace std; class Student { public: Student(); // constructor Student(string studentname, int studentid, double studenttuition); // constructor overloading Student(Student& student); // copy constructor string getname(); // accessor int getid(); // accessor double gettuition(); // accessor void setname(string StudentName); // mutator void setid(int studentid); // mutator void settuition(double studenttuition); // mutator private: string name; int id; double tuition; ; Public vs Private - The variables and functions declared as private cannot be referenced anywhere except within the class functions. - The variables and functions declared as public can be referenced anywhere. Abstract Data Types (ADTs): - A data type where the programmers who use this class do not have access to the details of how the values and operations are implemented. - Also known as data hiding, data abstraction, and encapsulation. - Typically, a consumer of the class needs to be aware of all the public fields. Scope Resolution Operator :: - When a member function is defined, the definition must include the class name because there may be two or more classes that have member functions with the same name. - Without it, the compiler does not know which class member function the definition is for. Examples: string Student::getName() { return name; int Student::getId() { return id; double Student::getTuition() { return tuition; void Student::setName(string studentname) { name = studentname; void Student::setId(int studentid) { id = studentid; void Student::setTuition(double studenttuition) {
Accessor and Mutator Functions - A function that simply returns private members values are called accessor functions (i.e. they access the data) - getname(), getid(), gettuition() are examples of accessor functions. - A function that simply sets private members values are called mutator functions (i.e. they change the data). - setname(), setid(), settuition() are examples of mutator functions. Structures vs Classes - In general, a C++ struct can do anything a C++ class can do! - including having functions, inheritance, public / private members - Default behavior is different: o If public or private is not defined, structs default to public and classes default to private. Constructors - A special kind of function with the same class name that it s defined in. - A constructor is called when an object of that class is declared. - Constructors are the only functions that do not have a return type. - The only time you will use a constructor is during declaration. - Default constructors can be defined by you (which is good style). - If a default constructor is not defined, the compiler will generate one if no other constructor is defined! Otherwise it will not. // Example of default constructor Student::Student() { name = John Doe ; id = 0; tuition = 0.0; // Example of constructor overloading Student::Student(string studentname, int studentid, double studenttuition) { name = studentname; id = studentid; Copy Constructor - Take in an existing Object in a constructor's parameter and set all of its fields to the fields of the object, thus copying one object's fields to the current object. - Copy constructors must pass its parameter by reference Pass- by- value vs. Pass- by- reference - Also know as call- by- value and call- by- reference. - Pass- by- value copies the parameter value into a variable that is local to the function.
- Pass- by- reference modifies the value in memory and does not create a local copy. // Example of copy constructor Student::Student(Student& student) { id = student.getid(); name = student.getname(); tuition = student.gettuition(); Arrays - Used to process a collection of data of the same type. Statically- allocated arrays int a[10]; - The array will have a size of 10 * sizeof(int). - Be careful! Arrays do not know what their size is! Bracket Syntax - Accessing an individual cell of an array uses a traditional [ ] syntax, which is indexed starting at 0. - For all practical purposes, a specific element in an array can be treated as a type that the array was defined as. Passing Arrays as parameters You can pass arrays in parameters as you would expect, but there are some things to take into consideration: 1. The value that is actually passed into the function is the address of the 0 th index of the array. 2. Arrays do not inherently have a size associated with it (i.e..size() or.length()), therefore you should pass the size of the array as a separate parameter. void printarray(char grades[], int size) { for (int i = 0; i < size; i++) { cout << a[ << i << ] = << a[i] << endl; Multi- dimensional Arrays int grid[4][6]; // 2-D 4x6 array (or 4 1-Dimensional arrays of size 6)
Example of initialization / looping through a 3- D array: int grid[2][3][2] = {{0,1, {2,3, {4,5, {{6,7,{8,9,{10,11; for (int i = 0; i < 2; i++) { for (int j = 0; j < 3; j++) { for (int k = 2; k < 2; k++) { cout << grid[i][j][k] <<, ; Passing multidimensional arrays as parameters in functions - When passing in a multi- dimensional array, the size of each dimension (except the first) must be defined in the parameter. - Note: it s legal to pass in the 1 st dimension s size, but it s not necessary since the compiler ignores it. void somefunction(int grid[][6], int size) { Example Organization of breaking the Student Class into multiple files: // student.h #ifndef STUDENT_H #define STUDENT_H #include<string> class Student { public: Student(); Student(std::string studentname, int id, double tuition); Student(Student& student); std::string getname(); int getid(); double gettuition(); void setname(std::string studentname); void setid(int studentid); void settuition(double studenttuition); private: std::string name; int id; double tuition; ; #endif - - - - - - - - - - - - - //student.cpp #include "student.h" #include<string> using namespace std;
Student::Student() { name = "John Doe"; id = 0; tuition = 0; Student::Student(string studentname, int studentid, double studenttuition) { name = studentname; id = studentid; Student::Student(Student& student) { id = student.getid(); name = student.getname(); tuition = student.gettuition(); string Student::getName() { return name; int Student::getId() { return id; double Student::getTuition() { return tuition; void Student::setName(string studentname) { name = studentname; void Student::setId(int studentid) { id = studentid; void Student::setTuition(double studenttuition) { - - - - - - - - - - - - - // main.cpp #include<iostream> #include<string> #include"student.h" using namespace std; int main() { Student me1("richert", 12345678, 0.5); Student me = Student(me1); cout << "Name: " << me.getname() << endl; cout << "Id: " << me.getid() << endl; cout << "Tuition: " << me.gettuition() << endl; return 0; Note: You should not use using namespace in your header files. This can have unintended side- effects for consumers of this header that are not expecting to use a namespace.