(C++) Exercise
January 25, 2018 · View on GitHub
(C++) Exercise



On this page you can find some exercises about correct programming, inspired by Herb Sutter's 'Guru Of The Week' pages.
These exercises are suitable for experienced beginners, that want to learn to think in the C++ way. As a side-result they will learn more advanced concepts in a playful way. I try to work on the same difficulty scale as Herb Sutter.

Exercise #0: A correct
Divide function
Exercise #1: A foolproof
function
Exercise #2: Correct
function declarations
Exercise #3: Don't give
away your internals
Exercise #4: Reading
from a std::vector safely
Exercise #5: The many
types of const
Exercise #6: refactoring
quadratic solver
Exercise #7: add
one
Exercise
#8: library trouble
Exercise #9: no
for-loops
Exercise #10: Obtaining
a read-only (smart?) pointer
Exercise #11: Obtaining
a std::vector of read-only (smart?)
pointers
Exercise #12: Qt hide and
show #1: intro
Exercise #13: Qt hide and
show #2: the real problem
Exercise #14: Qt hide and
show #3: refactoring
External links
Additionally, Exercise is a class for an exercise.
Technical facts
./CppExercise/CppExercise.pri
INCLUDEPATH += \ ../../Classes/CppExercise SOURCES += \ ../../Classes/CppExercise/exercise.cpp HEADERS += \ ../../Classes/CppExercise/exercise.h OTHER_FILES += \ ../../Classes/CppExercise/Licence.txt
./CppExercise/exercise.h
//--------------------------------------------------------------------------- /* Exercise, a collection of Questions Copyright 2011-2015 Richel Bilderbeek This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program.If not, see <http://www.gnu.org/licenses/>. */ //--------------------------------------------------------------------------- //From http://www.richelbilderbeek.nl/CppExercise.htm //--------------------------------------------------------------------------- #ifndef EXERCISE_H #define EXERCISE_H #include <string> #include <vector> #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Weffc++" #include <boost/shared_ptr.hpp> #pragma GCC diagnostic pop namespace ribi { ///A Exercise is a collection of questions struct Exercise { ///Construct a Exercise from file ///The file needs to contain at least one question ///Throws std::logic_error if file does not exist ///Throws std::runtime_error if file does not contain a single question explicit Exercise(const std::string& filename); ///Read the current question std::string GetCurrentQuestion() const noexcept; ///Get the number of questions, will be at least one int GetNumberOfQuestions() const noexcept; ///Obtain this class its version static std::string GetVersion() noexcept; ///Obtain this class its version history static std::vector<std::string> GetVersionHistory() noexcept; ///Go to the next question void Next() noexcept; private: ~Exercise() noexcept {} friend void boost::checked_delete<>(Exercise *); friend void boost::checked_delete<>(const Exercise *); ///An iterator pointing to the current question std::vector<std::string>::iterator m_current; ///The questions std::vector<std::string> m_questions; }; } //~namespace ribi #endif // EXERCISE_H
./CppExercise/exercise.cpp
//--------------------------------------------------------------------------- /* Exercise, a collection of Questions Copyright 2011-2015 Richel Bilderbeek This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program.If not, see <http://www.gnu.org/licenses/>. */ //--------------------------------------------------------------------------- //From http://www.richelbilderbeek.nl/CppExercise.htm //--------------------------------------------------------------------------- #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Weffc++" #pragma GCC diagnostic ignored "-Wunused-local-typedefs" #include "exercise.h" #include <fstream> #include <stdexcept> #include <boost/numeric/conversion/cast.hpp> #include "fileio.h" #include "multiplechoicequestion.h" #include "multiplechoicequestiondialog.h" #include "openquestion.h" #include "openquestiondialog.h" #include "openquestiondialogfactory.h" //#include "trace.h" #include <QFile> #pragma GCC diagnostic pop ribi::Exercise::Exercise(const std::string& filename) : m_current{}, m_questions{} { assert(QFile::exists(filename.c_str())); if (!QFile::exists(filename.c_str())) { throw std::logic_error("File does not exist"); } const std::vector<std::string> v { ribi::fileio::FileIo().FileToVector(filename) }; m_questions.reserve(v.size()); for(const std::string& s: v) { try { boost::shared_ptr<QuestionDialog> tmp = OpenQuestionDialogFactory().Create(s); m_questions.push_back(s); continue; } catch (std::exception&) { //No problem } try { boost::shared_ptr<QuestionDialog> tmp(new MultipleChoiceQuestionDialog(s)); m_questions.push_back(s); continue; } catch (std::exception&) { //No problem } } if (m_questions.empty()) { throw std::runtime_error("No questions found in loading the Exercise"); } assert(!m_questions.empty()); //Shuffle the questions at start std::random_shuffle(m_questions.begin(),m_questions.end()); m_current = m_questions.begin(); assert(m_current != m_questions.end()); } std::string ribi::Exercise::GetCurrentQuestion() const noexcept { assert(m_current != m_questions.end()); return *m_current; } int ribi::Exercise::GetNumberOfQuestions() const noexcept { assert(!m_questions.empty()); return boost::numeric_cast<int>(m_questions.size()); } std::string ribi::Exercise::GetVersion() noexcept { return "1.1"; } std::vector<std::string> ribi::Exercise::GetVersionHistory() noexcept { return { "2011-09-26: Version 1.0: initial version", "2011-10-30: Version 1.1: shuffle questions at start" }; } void ribi::Exercise::Next() noexcept { ++m_current; if (m_current == m_questions.end()) { std::random_shuffle(m_questions.begin(),m_questions.end()); m_current = m_questions.begin(); } }