# Redesigning a C++ Course

I'm trying to teach C++ to postgraduate students, some of whom have no coding experience. A previous lecturer has left powerpoint presentations and videos but they're simply not engaging enough and nothing sticks in the student's minds. We teach Python via Jupyter notebooks, which works well, although the subject matter is easier. I found an C++ version of jupyter notebooks but I'm not sure it's appropriate for C++ (It's not helped C+ is such a big sprawling language that it's hard to cut down easily.

What is considered best practice for teaching C++ in 2022. I'm leaning towards thinking a traditional lecture is pretty much the worst way to go, but I'm not sure whether it's just difficult regardless.

What do you think is a realistic level for students to get to learning C++, given 40 hours of labs, seminars and zoom meetings (in total)?

• What level are your students? High school? College? And what do you mean by 40 hours of contact time? You only see them for 40 hours? May 11 at 12:41
• Can I say I wish I'd spoken to you both about 10 weeks ago! May 11 at 14:21
• For those with no coding experience… can you start with something other than C++? May 11 at 21:01
• Can you explain why c++? It doesn't seem to make much sense for this group of non-coders. Python and many other options (eg R, Matlab, Mathematica...) likely make more sense as they are easier to start with plus students are more likely to use them afterward. May 12 at 7:35
• Why are your students learning C++? What is the goal of the class? If they're postgrads, I assume they're highly specialized in some discipline or another (are they all from the same background, if so, which, if it's relevant?) and are in the class in some context of that discipline. This would have a potentially large impact on what you're teaching and how you approach it relative to a random general audience wanting to pick up coding basics. C++ and programming in general are huge topics and there are so many approaches depending on goals. May 14 at 18:34

You are looking at a room full of post-grad students, who are thus convinced of their superior intelligence, some of whom have zero programing experience... I think your only hope is to lean into live coding.

Whatever you do, don't try to start off with a huge example that shows everything all at once, thinking that you will slowly introduce and describe the basics after the fact. This will only intimidate and discourage the newbies.

Start off with the basics, move as quickly as the students will allow and demonstrate everything in the compiler yourself as you go along. In addition to seeing the concepts work in the real world, the code they are creating also acts as note taking and gives them a reference for the future.

Once you are rolling you can fast forward through topics when you see that the students are groking the basics. Covering everything, but spending as little time on it as possible: This is an IDE, it lets you build and compile a program. Commands look like this, notice the dot / arrow notation, it will become important. Variables have a type and hold values. Basic arithmetic looks like this, notice how values are accumulated. Looping and conditions are managed thusly, see how we can nest the structures together. Methods help with organization and are the most awesome boring topic in existence.

What will make all of this stick is having the students code it along with you. Create a basic program demonstrating it all live as you type it in, while the students follow along tying it in on their own computers. Pause after each major topic to give them a chance to solve a mini problem where they use the tool on their own.

Stay away from pointers and references. I know the ideas are at the core of C/C++ but * and -> notation is enough to send any newbie away screaming.

After each meeting, leave them with some homework. Have them create a project that highlights what they learned, incorporating as many of the past topics as possible. Make the projects as fun and interesting as possible, incorporating graphics as much as you can, even if this means giving them 90% of an app as a starting framework for them to build on.

The more experienced the students get, the more confident they get in their ability, the more time you can spend on lecture instead of demonstration.

Finally, save class structure for the very end. After they have been creating static methods and local/global variables for a while, the idea of encapsulating it all into an object that can have multiple instances should now fit into their brains. This is also the time to introduce the idea of pointers and references.

Now... does all that qualify as best practice? Meh, I don't think there is such a thing in teaching. While I can back it up by mentioning that I have 15 years of experience teaching at both the high school and college level, it is all of course only my humble opinion.

• In general I agree with your answer but I disagree on classes. Students don’t seem to have much trouble with it and on the contrary they seem to appreciate the elegance of code organization. Maybe it helps that I give them exercises that are elegantly expressed with objects. May 11 at 14:32
• Agree to disagree. I have students that get organization right from the start, but most students need to drink in the idea of coding and confront a page full of endless left justified code before the need for organization sinks in. Functions is actually the second topic I cover in my intro course -- right after they get to know the IDE. But, I don't touch on objects in intro at all. The organization of class structure is straight forward, but the fact that you can instantiate multiple instances of the class, each with its own instance variables, can be a bitter pill to swallow. May 11 at 14:58
• Happy to disagree. I used to teach structs before classes, just to get the notion of "bundle of data" in to their heads. Have since stopped mentioning structs altogether, but the examples / exercises still have objects that are data-like. For instance class Point { double x,y; ...... } so that you can have Point Point::shift(....) and Rectangle::Rectangle( Point,Point ) (rectangle from topleft/botright points). I don't recall there ever being a problem with that. (Are your materials online?) May 11 at 16:04
• If you are not going to teach pointers or references, it is an indication that you shouldn't be teaching C/C++ - they are fundamental to the way the language works and the benefits that C++ has over e.g. Java (the complexity of C++ is the cost you pay for that benefit). +1 for live coding though. May 15 at 7:37
• @Dikran Marsupial I would tend to agree. C/C++ should not be the language you try to teach to first semester students. However, if you are stuck starting students out in C/C++ you should try to soften the blow as much as possible and leave the ramifications of pointer manipulation until they have some mastery over the basic idea. May 16 at 12:08

I agree that pure lecturing is really bad. I let students do lots of exercises, including during class time. (And just to prove that lecturing is bad: two minutes after they have seen something on a slide they can not remember it for their lab exercise.)

The reason I like doing labs in lecture time is that I walk through the class (with a co-teacher) and look over everyone's shoulder. Tell them "That's good" or "I see you're stuck, take a look at...." or "You can do it that way, but I like .... because ....".

Feel free to use my book. Item 3 on: https://theartofhpc.com/ It comes with sources for the slides, lots of example programs, and skeleton codes for exercises to get them started. Everything is up to C++17 standards. There are also some fairly nifty end-of-semester coding projects.

• Formative assessment at it's finest. :-) May 11 at 14:18
• @codingCat Right. Giving them a week to get completely stuck on a homework assignment is the best way to lose them entirely. May 11 at 16:14

Your instincts are correct - there are alternatives to lecturing, but every pedagogical method has its place. I generally reserve lectures as an opportunity to highlight a few difficult concepts from the text and address questions.

I favor OER textbooks, a flipped classroom, and students working on assignments in class. Assignments could be either straight programming tasks or guided exercises. Not sure what content you plan to focus or how dirty you want to get, but there are several decent C++ OER books based on Sphinx/docutils:

1. OpenDSA is an interactive open data structures textbook, but people are growing it beyond data structures content. It has config files allowing you to customize your own textbook. I used it years ago, but found working in the environment harder than I liked.
2. Runestone Academy is a general framework for creating interactive OER. My current textbook uses Runestone, but I self-host (on GitHub pages) so that the book is 100% free for students. Runestone can host your course for you, but there are some (small) fees for students. I have not looked deeply into it.

Both of these environments support assessments in the text, but otherwise, the details are different. If you are already familiar with Sphinx-doc, I think Runestone has a short learning curve. If you want to see a self-hosted example (my textbook). Book source is on GitHub. A first semester version based on How to Think Like a Computer Scientist is a work in progress. You could look at that outline to get a sense of what is reasonable for a single semester.

Another thing to consider are the assignments themselves. Most of my assignments are in the style of Exercism.io. Students are presented with a programming problem and they need to write code that passes the unit tests. Most students find this approach both challenging and engaging.

Another approach useful in a flipped classroom is POGIL. There is a Process Oriented Guided Inquiry Learning (POGIL) in Computer Science group and they provide activities, training, mentoring, and POGIL workshops-on-request. I have found them to be quite responsive and helpful.

Whatever you do, focus on getting students to write code. You can listen to classical music your whole life and never learn to play an instrument. Programming is not a spectator sport.

As far as content, I prefer to teach a more modern version of C++. Generally, I'm in alignment with codingCat - I focus on coding as much as is possible -> the type system, string and vector first, then functions, structures, and classes mostly in that order - although I use POD's from the first few weeks. I will say that unlike codingCat, I cover pointers and references (not in that order) when I cover passing semantics for functions. Something to consider is that if you focus on (post?)-modern C++, you can write much more code that appears to have pass by value semantics, but isn't (move semantics). You can have your examples look simple and then once the basics are understood explain the magic that make the simple looking stuff happen (e.g. move semantics).

I see a lot of courses in a big hurry to teach OO right away. There are a lot of pitfalls to be aware of in OO and C++ is already a language with more pitfalls than most. Classes are collections of functions and data. If students can't write decent functions, then they are unlikely to write decent classes. Classes are everything that functions are and more. Also, C++ is a multi-paradigm language - people need to expect that not everything will be in a class. This can become a religious war, but I assume you have a course outline you are required to follow, so do what you have to do.

I also teach at the University level and have found great success in teaching C++ by doing visual & interactive program examples, exercises and assignments.

Something like the Coding Train's Intro Programming but with C++. You could use raylib to help provide simple drawing and interactivity.

Hope this helps!

I teach C and C++ in the second year, who were taught Java in the previous year by myself and a colleague. Due to COVID I pre-recorded the lectures I used to give so that the students could watch them in their own time. I indexed the videos at each change of slide so that they could easily navigate to the bit they wanted, which seemed a good compromise between having lots of short unconnected videos and an overly long traditional lecture. The idea was that they would watch the videos, and if they had questions or wanted me to go over examples of something, they could let me know (via a discussion forum) and I would give a live lecture later in the week (just before the lab) which would be a mixture of explaining answers to questions with new slides generated for that week, informal Q&A and live programming demos (my traditional lectures also had lots of that).

This approach seems to work well - many students are uncomfortable asking questions out loud in a live lecture, but were much more comfortable with the chat facility used in the remote live lectures, so there was much more interaction than before and I could be more responsive to student's difficulties/questions.

Different people like to learn in different ways, and this approach works whether you actually like watching formal programming lectures, or just want to watch them in sped-up 10 minutes sections, or ignore them altogether and read books/experiment with the computer.

The key thing is for the lab classes and exercises to be well designed and get the concepts in the right order.

As we do C and then C++, we cover pointers and memory allocation in C. Note: we teach C and C++ as distinct goals, we are not teaching C purely as a prelude to C++. This is a major stumbling block for students to it is important they understand it properly at an early stage. As they have done Java the year before, they find the concept of the variable actually being the object (rather than a reference) rather difficult and they tend to write very inefficient C++ code, so that is also something to emphasize early. Being from a Java background they have difficulties with C++ references because Java references are epsilon different from a C pointer and the terminology confuses. I approach classes via structs which we did earlier in the C part of the course.

• C "pointers" are really memory addresses, and are almost never needed in C++. So if you're teaching that on the way to C++ it's a waste of effort, and you'll probably teach them bad habits. C++ does have real pointers, usually called "smart pointers", but those are not needed in many applicaitons. In other words, I disagree with many aspects of your teaching strategy. May 16 at 21:09
• Well, you wrote "As we do C and then C++" so it does sound like you're using C as a precursor to C++. For what it's worth, I teach C++ first, and then show how some things that are simple in C++ can be hacked around in C. May 16 at 21:23
• What you call "pointers" are not pointers. They are addresses. Smart pointers are to your "pointers" as std::vector is to automatic arrays: a better way to do stuff that is error-prone in C. You can perfectly well use smart pointers to implement linked lists and such with out ever having seen C "pointers". A wider point about "understanding things": it's called abstraction. You can teach to a level of abstraction, and as long aas that's a consistent and rich enough vocabulary, you don't have to teach the layer below it. So: I teach std::vector and not new x[5]; ditto pointers. May 19 at 12:58
• Well, I do point out the costs of re-allocation in std::vector, in the abstract. I think the lower layer should only be taught when it has a detectable impact. May 19 at 15:25
• You're right, I don't care about linked lists as such. However, linked lists are the simplest example of a Directed Acyclic Graph. And DAGs are very common in computational science. May 19 at 15:42

If the point is to learn C++, you must learn C. Must. You must understand addresses, pointers, structures, argument passing, memory allocation, the stack and a backtrace. You must understand implicit conversions and the difference between floating point and integer math and the limits and sizes of built-in types. You must understand linkage. Any way you do it, you can't escape these topics.

• Learning C is actively detrimental to learning C++. Yes, you must learn pointers, linkage, etc. but there is no reason to learn C itself since a great many things in C have been superseded in modern C++ (or even old C++). May 13 at 11:47
• @JackAidley the fact that a lot of systems programming is (best) done in C is a good reason to learn C. The other advantage of C is that the students are capable of fully understanding it all as they learn, because it is all very simple and nothing is hidden. Learning C++ directly requires the students to take a lot on trust, and using things without understanding what you are doing seems somewhat antithetical to university education (and is a bad habit students easily fall into because the are often goal-directed). Both approaches have advantages/disadvantages. May 15 at 8:02
• @DikranMarsupial There may be many good reasons to learn C, but in order to learn C++ is not one of them. May 15 at 10:34
• @JackAidley C++ is a superset of C, you can't learn C++ without learning C, it is just a matter of emphasis on which parts of it you use. If you want to learn OOP, then learning Java first is better than C++. C++ is no longer a good language to learn first (as it was back in the late 1980s) - it is too complex and compilers too unfriendly (due to the complexity of the language). May 15 at 12:05
• @DikranMarsupial It is not true that you need to learn the C subset in order to learn C++. Many C features have been superseded in C++ and are rarely used in C++ - certainly not at the beginner level. malloc/free would be the most obvious but there are others. What's more the way you program in C and the way you program in C++ are different, learning the C way - as a beginner - is unhelpful to learning the C++ way. May 15 at 14:42

You need to stay within the zone of proximal development.

Learning C++, and learning to program at the same time, is too big a step. People can not learn too much at one time.

Therefore students should first learn to program, then (if needed) learn C++.

The ideal language to use when learning to program will be a language that does not need learning, because it has no or little syntax.

In by experience, (tutoring university students, and working with graduates) Java it too complex to use as a teaching language. Students spend too much time stuck, too much time trying to learn the language, while still having no idea how to program. They can learn to program, because they don't know the language. They can learn the language, because they can't program. If they don't get help to learn to program via a different language, or have “the right stuff“, then they end up not being able to program.