online compiler and debugger for c/c++

code. compile. run. debug. share.
Source Code   
Language
#include "intpair.hpp" #include "pair.hpp" #include <iostream> #include <iomanip> #include <cassert> #include <string> // Note: // All of our pair classes have the same interface, specifically: // - A default constructor // - A copy constructor // - An assignment operator // - A constructor that takes two arguments // - A getFirst() member function // - A getSecond() member function // - A setFirst() member function // - A setSecond() member function // - A combine() member function // - A printToStream() member function // - A non-member operator<<() function int main() { // We can make a pair of ints and print it using IntPair. IntPair ipair0{40, 2}; std::cout << "ipair0: " << ipair0 << " [requires " << sizeof(ipair0) << " bytes]" << std::endl; // But we can also make a pair of ints and print it using our Pair class // template to make an instantiation of our template that holds two ints. Pair<int, int> pair0{40, 2}; std::cout << "pair0: " << pair0 << " [requires " << sizeof(pair0) << " bytes]" << std::endl; // In recent versions of C++, it can deduce the types of the template // arguments, so we could also write: Pair apair0{40, 2}; std::cout << "apair0: " << apair0 << " [requires " << sizeof(apair0) << " bytes]" << std::endl; // Note that the type of apair0 is still Pair<int, int>, we just didn't // have to write it out. In CS 70, we prefer not to use this feature // (which was added in C++ 17) and instead be explicit about the types, // since it avoids confusion about what's going on. // When executed, the code above prints: // ipair0: (40, 2) [requires 8 bytes] // pair0: (40, 2) [requires 8 bytes] // apair0: (40, 2) [requires 8 bytes] // which helps confirm that all three pairs are represented the same way // in memory. ipair is an IntPair, pair0 is a Pair<int, int>, and apair0 // is also a Pair<int, int> (but we didn't have to write that out). std::cout << "pair0.combine(): " << pair0.combine() << std::endl; // Here instead of saying // Pair<double, double> pair1{3.14, 2.718}; // we'll use our setter member functions to set the values Pair<double, double> pair1; pair1.setFirst(3.14); pair1.setSecond(2.718); std::cout << "pair1: " << pair1 << std::endl; std::cout << "pair1.combine(): " << pair1.combine() << std::endl; // Make a pair with two different kinds of values in it Pair<float, bool> pair2{2.1, true}; pair2.setFirst(pair2.getFirst() * 2.0); std::cout << std::boolalpha; // print bools as "true" or "false" std::cout << "pair2: " << pair2 << std::endl; std::cout << "pair2.combine(): " << pair2.combine() << std::endl; // Create a pair of pairs Pair<Pair<double, double>, Pair<float, bool>> pair3{pair1, pair2}; std::cout << "pair3: " << pair3 << std::endl; // Make a pair on the heap Pair<int, int>* pair4ptr = new Pair<int, int>{pair0}; std::cout << "pair4ptr: " << pair4ptr << "; *pair4ptr: " << *pair4ptr << std::endl; // Clean up delete pair4ptr; return 0; }
#ifndef INTPAIR_HPP_INCLUDED #define INTPAIR_HPP_INCLUDED #include <iostream> class IntPair { public: IntPair() = default; // Synthesize the default constructor IntPair(const IntPair&) = default; // Synthesize the copy constructor IntPair& operator=(const IntPair&) = default; // Synthesize assignment operator IntPair(int f, int s); int getFirst() const; int getSecond() const; void setFirst(int f); void setSecond(int s); int combine() const; // Combine the 1st and 2nd values using the + operator void printToStream(std::ostream& out) const; private: int first_; int second_; }; std::ostream& operator<<(std::ostream& out, const IntPair& p); #endif // INTPAIR_HPP_INCLUDED
#include "intpair.hpp" #include <iostream> #include <iomanip> IntPair::IntPair(int f, int s) : first_{f}, second_{s} { // Nothing (else) to do } int IntPair::getFirst() const { return first_; } int IntPair::getSecond() const { return second_; } void IntPair::setFirst(int f) { first_ = f; } void IntPair::setSecond(int s) { second_ = s; } int IntPair::combine() const { return first_ + second_; } void IntPair::printToStream(std::ostream& out) const { out << "(" << first_ << ", " << second_ << ")"; } std::ostream& operator<<(std::ostream& out, const IntPair& p) { p.printToStream(out); return out; }
#ifndef PAIR_HPP_INCLUDED #define PAIR_HPP_INCLUDED #include <iostream> template <typename F, typename S> class Pair { public: Pair() = default; // Synthesize the default constructor Pair(const Pair&) = default; // Synthesize the copy constructor Pair& operator=(const Pair&) = default; // Synthesize assignment operator Pair(const F& first, const S& second); const F& getFirst() const; const S& getSecond() const; void setFirst(const F& f); void setSecond(const S& s); F combine() const; // Combine the 1st and 2nd values using the + operator void printToStream(std::ostream& out) const; private: F first_; S second_; }; template <typename F, typename S> std::ostream& operator<<(std::ostream& out, const Pair<F, S>& p); #include "pair-private.hpp" #endif // PAIR_HPP_INCLUDED
// This file implements the class template Pair, whose class definition // is in pair.hpp. You might expect this file to be called pair.cpp, // but templates are implemented in header files, not source files, // because the compiler needs to see the implementation of the template // in order to generate the code for specific instantiations of the // template. This is why we have the #include "pair-private.hpp" at // the end of pair.hpp. (We could have put the implementation of the // template in pair.hpp, but that file can be seen as specifying the // interface of the class template, and the implementation is a // separate concern, so it belongs in a separate file.) #ifndef PAIR_HPP_INCLUDED #warning "pair-private.hpp should not be included directly" #endif template <typename F, typename S> Pair<F, S>::Pair(const F& first, const S& second) : first_{first}, second_{second} { // Nothing (else) to do } template <typename F, typename S> const F& Pair<F, S>::getFirst() const { return first_; } template <typename F, typename S> const S& Pair<F, S>::getSecond() const { return second_; } template <typename F, typename S> void Pair<F, S>::setFirst(const F& f) { first_ = f; } template <typename F, typename S> void Pair<F, S>::setSecond(const S& s) { second_ = s; } template <typename F, typename S> F Pair<F, S>::combine() const { return first_ + second_; } template <typename F, typename S> void Pair<F, S>::printToStream(std::ostream& out) const { out << "(" << first_ << ", " << second_ << ")"; } template <typename F, typename S> std::ostream& operator<<(std::ostream& out, const Pair<F, S>& p) { p.printToStream(out); return out; }

Compiling Program...

Command line arguments:
Standard Input: Interactive Console Text

                

                

Program is not being debugged. Click "Debug" button to start program in debug mode.

#FunctionFile:Line
VariableValue
RegisterValue
ExpressionValue