Download Understanding Classes and Structs: Vector and Point Examples and more Slides Data Structures and Algorithms in PDF only on Docsity! User-defined Datatypes Docsity.com Representing a (Geometric) Vector • In the context of geometry, a vector consists of 2 points: a start and a finish • Each point itself has an x and y coordinate Start = (0.4, 0.8) End = (0.9, 1.5) Docsity.com void printVector(double x0, double x1, double y0, double y1) { cout << "(" << x0 << "," << y0 << ") -> (" << x1 << "," << y1 << ")" << endl; } int main() { double xStart = 1.2; double xEnd = 2.0; double yStart = 0.4; double yEnd = 1.6; printVector(xStart, xEnd, yStart, yEnd); // (1.2,2.0) -> (0.4,1.6) } Docsity.com void offsetVector(double &x0, double &x1, double &y0, double &y1, double offsetX, double offsetY) { x0 += offsetX; x1 += offsetX; y0 += offsetY; y1 += offsetY; } void printVector(double x0, double x1, double y0, double y1) { cout << "(" << x0 << "," << y0 << ") -> (" << x1 << "," << y1 << ")" << endl; } int main() { double xStart = 1.2; double xEnd = 2.0; double yStart = 0.4; double yEnd = 1.6; offsetVector(xStart, xEnd, yStart, yEnd, 1.0, 1.5); printVector(xStart, xEnd, yStart, yEnd); // (2.2,1.9) -> (3.8,4.3) } Many variables being passed to functions Docsity.com class • A user-defined datatype which groups together related pieces of information Vector xStart xEnd yStart yEnd Docsity.com Fields can have different types class MITStudent { public: char *name; int studentID; }; MITStudent name studentID Docsity.com Instances • An instance is an occurrence of a class. Different instances can have their own set of values in their fields. • If you wanted to represent 2 different students (who can have different names and IDs), you would use 2 instances of MITStudent student1 name = ? studentID = ? student2 name = ? studentID = ? Docsity.com Declaring an Instance • Defines 2 instances of MITStudent: one called student1, the other called student2 class MITStudent { public: char *name; int studentID; }; int main() { MITStudent student1; MITStudent student2; } student1 student2 name = ? studentID = ? name = ? studentID = ? Docsity.com student1 student2 name = “Geza” studentID = 123456789 name = ? studentID = ? Accessing Fields • To access fields of instances, use variable.fieldName class MITStudent { public: char *name; int studentID; }; int main() { MITStudent student1; MITStudent student2; student1.name = "Geza"; student1.studentID = 123456789; student2.name = "Jesse"; student2.studentID = 987654321; } = “Jesse” = 987654321 Docsity.com Accessing Fields • To access fields of instances, use variable.fieldName class MITStudent { public: char *name; int studentID; }; int main() { MITStudent student1; MITStudent student2; student1.name = "Geza"; student1.studentID = 123456789; student2.name = "Jesse"; student2.studentID = 987654321; cout << "student1 name is" << student1.name << endl; cout << "student1 id is" << student1.studentID << endl; cout << "student2 name is" << student2.name << endl; cout << "student2 id is" << student2.studentID << endl; } Docsity.com Start = (0.4, 0.8) End = (0.9, 1.5) • A point consists of an x and y coordinate • A vector consists of 2 points: a start and a finish Docsity.com Start = (0.4, 0.8) End = (0.9, 1.5) • A point consists of an x and y coordinate • A vector consists of 2 points: a start and a finish Point x y class Point { public: double x; double y; }; Docsity.com • A point consists of an x and y coordinate • A vector consists of 2 points: a start and a finish Point x y class Point { public: double x; double y; }; Vector Point (start) Point (end) x y x y Docsity.com • A point consists of an x and y coordinate • A vector consists of 2 points: a start and a finish Point x y class Point { public: double x; double y; }; class Vector { public: Point start; Point end; }; Vector Point (start) Point (end) x y x y Fields can be classes Docsity.com vec1 (instance of Vector) start (instance of Point) end (instance of Point) x=3 y=4 x=5 y=6 class Point { public: double x, y; }; class Vector { public: Point start, end; }; int main() { Vector vec1; vec1.start.x = 3.0; vec1.start.y = 4.0; vec1.end.x = 5.0; vec1.end.y = 6.0; } Docsity.com vec2 (instance of Vector) start (instance of Point) end (instance of Point) x=? y=? x=? y=? class Point { public: double x, y; }; class Vector { public: Point start, end; }; int main() { Vector vec1; vec1.start.x = 3.0; vec1.start.y = 4.0; vec1.end.x = 5.0; vec1.end.y = 6.0; Vector vec2; } vec1 (instance of Vector) start (instance of Point) end (instance of Point) x=3 y=4 x=5 y=6 Docsity.com vec2 (instance of Vector) start (instance of Point) end (instance of Point) x=3 y=4 x=? y=? class Point { public: double x, y; }; class Vector { public: Point start, end; }; int main() { Vector vec1; vec1.start.x = 3.0; vec1.start.y = 4.0; vec1.end.x = 5.0; vec1.end.y = 6.0; Vector vec2; vec2.start = vec1.start; } vec1 (instance of Vector) start (instance of Point) end (instance of Point) x=3 y=4 x=5 y=6 • Assigning one instance to another copies all fields Docsity.com Passing classes to functions • When a class instance is passed by reference, changes are reflected in the original class Point { public: double x, y; }; void offsetPoint(Point &p, double x, double y) { // works p.x += x; p.y += y; } int main() { Point p; p.x = 3.0; p.y = 4.0; offsetPoint(p, 1.0, 2.0); // works cout << "(" << p.x << "," << p.y << ")"; // (4.0,6.0) } Passed by reference Docsity.com class Point { public: double x, y; }; Point class, with fields x and y Docsity.com class Point { public: double x, y; }; class Vector { public: Point start, end; }; Fields can be classes Docsity.com class Point { public: double x, y; }; class Vector { public: Point start, end; }; int main() { Vector vec; vec.start.x = 1.2; vec.end.x = 2.0; vec.start.y = 0.4; vec.end.y = 1.6; } Docsity.com class Point { public: double x, y; }; class Vector { public: Point start, end; }; void printVector(Vector v) { cout << "(" << v.start.x << "," << v.start.y << ") -> (" << v.end.x << "," << v.end.y << ")" << endl; } int main() { Vector vec; vec.start.x = 1.2; vec.end.x = 2.0; vec.start.y = 0.4; vec.end.y = 1.6; printVector(vec); // (1.2,0.4) -> (2.0,1.6) } classes can be passed to functions Docsity.com class Point { public: double x, y; }; class Vector { public: Point start, end; }; void printVector(Vector v) { cout << "(" << v.start.x << "," << v.start.y << ") -> (" << v.end.x << "," << v.end.y << ")" << endl; } int main() { Vector vec; vec.start.x = 1.2; vec.end.x = 2.0; vec.start.y = 0.4; vec.end.y = 1.6; printVector(vec); // (1.2,0.4) -> (2.0,1.6) } Can pass to value if you don’t need to modify the class Docsity.com Vector vec; vec.start.x = 1.2; vec.end.x = 2.0; vec.start.y = 0.4; vec.end.y = 1.6; vec.print(); Method name • Observe how some functions are closely associated with a particular class • Methods: functions which are part of a class Docsity.com • Observe how some functions are closely associated with a particular class • Methods: functions which are part of a class – Implicitly pass the current instance Vector vec; vec.start.x = 1.2; vec.end.x = 2.0; vec.start.y = 0.4; vec.end.y = 1.6; vec.print(); Object instance Docsity.com Vector vec; vec.start.x = 1.2; vec.end.x = 2.0; vec.start.y = 0.4; vec.end.y = 1.6; vec.print(); vec.offset(1.0, 1.5); Arguments can be passed to methods • Observe how some functions are closely associated with a particular class • Methods: functions which are part of a class – Implicitly pass the current instance Docsity.com Vector vec1; Vector vec2; // initialize vec1 and vec2 vec1.print(); vec1 print offset vec2 print offset Which button was pressed? Docsity.com class Vector { public: Point start; Point end; void offset(double offsetX, double offsetY) { start.x += offsetX; end.x += offsetX; start.y += offsetY; end.y += offsetY; } void print() { cout << "(" << start.x << "," << start.y << ") -> (" << end.x << "," << end.y << ")" << endl; } }; methods Docsity.com class Vector { public: Point start; Point end; void offset(double offsetX, double offsetY) { start.x += offsetX; end.x += offsetX; start.y += offsetY; end.y += offsetY; } void print() { cout << "(" << start.x << "," << start.y << ") -> (" << end.x << "," << end.y << ")" << endl; } }; Fields can be accessed in a method Docsity.com #include "vector.h" // vector.cpp - method implementation void Point::offset(double offsetX, double offsetY) { x += offsetX; y += offsetY; } void Point::print() { cout << "(" << x << "," << y << ")"; } void Vector::offset(double offsetX, double offsetY) { start.offset(offsetX, offsetY); end.offset(offsetX, offsetY); } void Vector::print() { start.print(); cout << " -> "; end.print(); cout << endl; } :: indicates which class’ method is being implemented Docsity.com Vector vec; vec.start.x = 0.0; vec.start.y = 0.0; vec.end.x = 0.0; vec.end.y = 0.0; • Manually initializing your fields can get tedious • Can we initialize them when we create an instance? Point p; p.x = 0.0; p.y = 0.0; Docsity.com Constructors • Method that is called when an instance is created class Point { public: double x, y; Point() { x = 0.0; y = 0.0; cout << "Point instance created" << endl; } }; int main() { Point p; // Point instance created // p.x is 0.0, p.y is 0.0 } Docsity.com • Recall that assigning one class instance to another copies all fields (default copy constructor) class Point { public: double x, y; Point() { x = 0.0; y = 0.0; cout << "default constructor" << endl; } Point(double nx, double ny) { x = nx; y = ny; cout << "2-parameter constructor" << endl; } }; int main() { Point q(1.0, 2.0); // 2-parameter constructor Point r = q; // r.x is 1.0, r.y is 2.0) } Invoking the copy constructor Docsity.com class Point { public: double x, y; Point(double nx, double ny) { x = nx; y = ny; cout << "2-parameter constructor" << endl; } Point(Point &o) { x = o.x; y = o.y; cout << "custom copy constructor" << endl; } }; int main() { Point q(1.0, 2.0); // 2-parameter constructor Point r = q; // custom copy constructor // r.x is 1, r.y is 2 } • You can define your own copy constructor Docsity.com • Why make a copy constructor? Assigning all fields (default copy constructor) may not be what you want int main() { MITStudent student1; student1.studentID = 98; char n[] = "foo"; student1.name = n; MITStudent student2 = student1; student2.name[0] = 'b'; cout << student1.name; // boo } class MITStudent { public: int studentID; char *name; MITStudent() { studentID = 0; name = ""; } }; By changing student 2’s name, we changed student 1’s name as well Docsity.com Access Modifiers • public: can be accessed from anywhere class Point { public: double x, y; Point(double nx, double ny) { x = nx; y = ny; } }; int main() { Point p(2.0,3.0); p.x = 5.0; // allowed } Docsity.com Access Modifiers • private: can only be accessed within the class class Point { private: double x, y; public: Point(double nx, double ny) { x = nx; y = ny; } }; int main() { Point p(2.0,3.0); p.x = 5.0; // not allowed } Docsity.com Access Modifiers • Use getters to allow read-only access to private fields class Point { private: double x, y; public: Point(double nx, double ny) { x = nx; y = ny; } double getX() { return x; } double getY() { return y; } }; int main() { Point p(2.0,3.0); cout << p.getX() << endl; // allowed } Docsity.com Default Access Modifiers • struct: public by default • class: private by default struct Point { double x, y; }; Equivalent to struct Point { public: double x, y; }; class Point { double x, y; }; class Point { private: double x, y; }; Equivalent to Docsity.com Docsity.com