UPI Study › Courses › C++ Programming › Free lessons › Lesson 9.2 Free with a free account
Making Structs Smarter
C++ Programming · Chapter 9: Structs, Classes, and File StreamsSection 9.2 · lesson 60 of 84video coming soon
← Bundling Related Fields With StructsNext lesson: Classes With Member Functions →
In this lesson
Adding functions and flexible containers.
- Add member functions to a struct, and call them
- Nest strings, vectors and structs inside structs
- Use a vector of structs as a table, and search it
- Sort by any field with a comparator; struct versus class
Transcript
Everything said in the video, section by section (1,132 words). Read along, or search it.
Opening Idea
Structs That Act and Collect
A struct that only groups fields is already useful. It becomes far more useful once it can also do things, hold collections of its own, and be gathered into a collection itself. At that point, you have the shape almost every real program is built from: a list of records, each of which knows something about itself.
Definition
Member Functions Beside Their Data
So far, a struct has been a bundle of fields, with operations on it living in separate functions. C++ allows those operations to go inside the struct, beside the data they use. Here, book has a member function, is long, which returns whether pages is more than 400. And price per page divides the price by the pages. Two details are worth naming. Inside a member function, the struct's own fields are available by name. Pages means the pages of whichever book this function was called on, so there's no parameter to pass. And const after the parameter list marks the function as read-only. It promises not to modify the object, which lets it be called on books the caller has declared unchangeable.
Worked Example
Asking a Book About Itself
Notice how the call reads. Atlas dot is long asks a book about itself. That's closer to the way the requirement was probably written than is long of atlas would be. And the gain isn't only stylistic. The test for long now lives in exactly one place, next to the field it depends on, so a change to the threshold can't be missed elsewhere. Run it: the atlas is long, and costs about 1.76 per page. Member functions may also be defined outside the struct, with the struct's name and two colons in front. Short functions are usually left inside. Longer ones are moved out, to keep the struct readable as a summary of what the type is.
Nested Fields
Chaining Dots Through Nested Records
A field may be of any type, including a string, a vector, or another struct. That's how real records are described. An address holds a city, a state, and a pin code. A member holds a name, a home address, which is a struct inside a struct, and a vector of borrowed titles. Reaching in is done by chaining the dot, one level per step. M dot name is a string. M dot home dot city is two steps in, and also a string. M dot borrowed, index zero, is indexed like any vector. And m dot borrowed dot size works, because it's a vector, so it knows its size. Each dot moves you inward, and the last thing in the chain is whatever type you finally arrived at. A vector member sizes itself, so a record with one borrowed book and a record with nine are both ordinary members. No maximum to pick, and no wasted space when the number is small.
Combining Ideas
A Vector of Structs as Rows
Put the two ideas together, and you have the arrangement that underlies most working software. A struct describes one row. A vector holds however many rows there are. Here, three books are pushed onto a shelf. The loop takes each by const reference, so there's no copy per pass, and prints its title and pages, marking the long ones. Atlas of Rivers and Almanac 2026 are marked long. Latin Primer isn't. The struct names the columns, and the vector supplies the rows: the subscript picks a row, and the dot picks a column.
Searching
Finding Records by Any Field
Because each record carries all its fields, a search can test whichever one the question is about. Find by title loops over the shelf, and returns the position of the first book whose title matches. If none does, it returns minus 1. Minus 1 isn't a valid index, so the caller can't mistake it for a result. Whatever convention you choose, the caller must check before using the answer. Collecting every match, rather than the first, is the same loop with a different destination. Every long book is pushed into a second vector. Run it: Latin Primer is at position 1, the missing title gives minus 1, and two books are long. The loop shape stays the same. Only the condition changes.
Sorting
Teaching Sort What Before Means
Sorting numbers or strings needs nothing extra, because the language already knows which of two comes first. It knows nothing like that about a book. And rightly, because the answer depends on the question. By title? By page count? By price? So you supply the answer as a comparator: a function taking two records, and returning true when the first should come before the second. By pages gives Latin Primer, Atlas of Rivers, then the Almanac. By title gives the Almanac first, then Atlas, then Latin Primer. By price descending gives the Almanac, Atlas, then Latin Primer. The comparator is the whole of the customization. You're not writing a sort. You're telling an existing one what before means for your type. And reversing needs no separate machinery. Flip less-than to greater-than, and the same call produces the opposite order.
Common Mistake
Never Use Or-Equal in Comparators
Your comparator must obey one rule. It must answer false when the two records are equal on the field being compared. Writing a dot pages less than or equal to b dot pages looks harmless, and isn't. It claims that a record comes before itself, a contradiction the sorting machinery is entitled to assume never happens. The consequences are undefined: a wrong order, or a crash. Use less-than or greater-than, never the or-equal forms.
Quick Check
Sorting by Author, Then Title
Quick check. How would you sort books by author, and within one author, by title? Pause and think. One comparator, with a tie-break. If the authors differ, that settles it. Only when they're equal does it fall through to comparing titles. Run it: Bose first, then the two Rao books in title order. A third field would be one more tie-break, written the same way.
Struct Versus Class
Only the Default Access Differs
Everything in this lesson works identically with the keyword class in place of struct. In C++, they're the same construct, and the language draws exactly one distinction. Members of a struct are accessible from outside by default. Members of a class aren't. Here is the real error when code touches a class member. Everything else is identical, and that default can be overridden either way, so the choice is a matter of convention, not capability. The convention: struct for a plain record whose fields are meant to be read and written freely, perhaps with a few small helpers. And class when the type has rules to enforce, so outside code goes through the operations you provide. That's the next topic.
Key Takeaways
Member Functions, Nesting, and Comparators Recapped
To summarize. Member functions sit inside the struct, beside the data they use. Chain the dot to reach fields nested inside other fields. A vector of structs is a table of records, searchable by any field. Sort it with a comparator that uses less-than or greater-than, never or-equal. And struct and class differ only in their default access.
About C++ Programming at UPI Study
C++ Programming (Computer Science 242) is a self-paced online course of 84 video lessons in 11 chapters, from your first program to decisions, loops, arrays, functions, classes, files, pointers and inheritance. It carries a NCCRS credit recommendation for 3 semester credits.
Every lesson transcript is free on pages like this one, and the videos are free with a free UPI Study account. Enrolling adds a practice quiz after each lesson, the graded work and final exam that earn the credit, lifetime access, and an official transcript on completion. UPI Study has helped over 130,000 students with college credits. ACE and NCCRS have over 2,100 cooperating colleges that will consider accepting credits; the final decision is with the universities.
Enroll now → Course details Download the syllabus Every course with PRO →
Why take it here
Why students take C++ Programming with UPI Study
Where the credit goes
Universities that work with NCCRS
C++ Programming carries a NCCRS credit recommendation. These universities work with NCCRS; some are UPI Study's signed partners. ACE and NCCRS have over 2,100 cooperating colleges that will consider accepting credits; the final decision is with the universities.
Thomas Edison State UniversitySigned partner
University of the PeopleSigned partner
Charter Oak State CollegeSigned partner
Strayer UniversitySigned partner
Columbia Southern UniversitySigned partner
Indiana TechSigned partner
Penn StateWorks with NCCRS
Southern New Hampshire UniversityWorks with NCCRS
SUNYWorks with NCCRS
+many more cooperating universitiesFind my college →Find my college → Not listed? Ask Athena in the corner of this page, or book a 15-minute call.
FAQ
Questions students ask us
About Making Structs Smarter
How do you add a member function to a struct in C++?
How do you search a vector of structs for a record by one field?
How do you sort a vector of structs by a field using a comparator?
Why should a sort comparator never use <= in C++?
About the C++ Programming course
How many college credits is C++ Programming?
How much does C++ Programming cost and what is included?
Which universities accept UPI Study credits?
How long does C++ Programming take?
How are the exams done?
How do my credits reach my college?
Ready for the full course? Earn 3 credits in C++ Programming.
84 video lessons, a quiz after each one, and the graded work that earns the credit. Recommended for credit by NCCRS.
3 credits · NCCRSEnroll →