#include // for std::size_t #include // for assert #include // for std::move #include // for std::out_of_range struct Person { Person (){} virtual int mark(){ return 0; } virtual ~Person(){} }; struct Student : Person { int m_mark; Student (int mark) : m_mark(mark) {} int mark() { return m_mark; } }; struct Pupil : Person { int m_mark; Pupil (int mark) : m_mark(mark) {} int mark() { return m_mark; } }; #include #include "shared_ptr.hpp" #ifdef SOLVED_1 using Ti::shared_ptr; using Ti::make_shared; using Ti::shared_dynamic_cast; #else using std::shared_ptr; using std::make_shared; #endif #include #include "array.hpp" #ifdef SOLVED_2 using Ti::array; using Ti::make_array; #else using std::array; #endif #include "mean_mark.hpp" #ifdef SOLVED_3 using Ti::mean_mark; using Ti::mean_mark_student; using Ti::remove_greater; #endif #include using std::vector; int main() { try { // initialize with new expression shared_ptr n1 (new Student(5)); assert (n1.get() != 0); shared_ptr n2 (new Person); assert (n2.get() != 0); throw 0; // must be exception safe } catch (...) {} { // derived1 is 0. shared_ptr derived1; assert(derived1.get() == 0); // Other way for object creation derived1 = make_shared(3); assert(derived1.get() != 0); // Call object member derived1->mark(); // Object creation with constructor parameters shared_ptr derived2 = make_shared(4); assert (derived2.get() != 0); shared_ptr base1 = make_shared(); assert (base1.get() != 0); // Implicit upcast possible. The object make_sharedd in the previous line is // destroyed, because there are no more pointers referencing it. base1 = derived1; #ifdef SOLVED_1 // Explicit downcast possible. Some casts that are available: constCast, // staticCast, dynamicCast derived2 = shared_dynamic_cast(base1); // You can compare pointers. assert(derived1 == derived2); #endif // Destroy most references to derived instance. References // (but not the object itself) are destroyed if they go out // of scope, or you can force reference destruction by multiple ways. derived1.reset(); // release reference assert(derived1.get() == 0); } { // array x; // Should fail with static assertion typedef array, 5> sarray; sarray a; a [0] = shared_ptr(new Student(2)); a [1] = shared_ptr(new Student(1)); a [2] = shared_ptr(new Student(5)); a [3] = shared_ptr(new Student(4)); a [4] = shared_ptr(); assert(a[0].get() != 0); assert(a[4].get() == 0); a [4] = shared_ptr(new Student(4)); try { a.at(5); // throws exception assert(0); } catch (std::out_of_range const& oor) { oor.what(); } catch (...) { assert(0); } #ifdef SOLVED_2 array a1 = make_array(); a1.fill(3); array a2 = make_array(); a2.fill(4); a1.swap(a2); assert(a1[0] == 4); assert(a2[2] == 3); #endif #ifdef SOLVED_3 double mean = mean_mark(a.begin(), a.end()); assert (mean >= 3.1 && mean <= 3.3); double mean_student = mean_mark_student(a.begin(), a.end()); assert (mean_student >= 3.1 && mean_student <= 3.3); sarray::iterator end = remove_greater(a.begin(), a.end(), 3); double mean2 = mean_mark(a.begin(), end); assert (mean2 >= 1.4 && mean2 <= 1.6); #endif } { typedef array, 5> parray; parray m; m [0] = shared_ptr(new Student(2)); m [1] = shared_ptr(new Pupil(1)); m [2] = shared_ptr(new Student(5)); m [3] = shared_ptr(new Student(4)); m [4] = shared_ptr(new Person()); #ifdef SOLVED_3 double mean = mean_mark(m.begin(), m.end()); assert (mean >= 2.3 && mean <= 2.5); double mean_student = mean_mark_student(m.begin(), m.end()); assert (mean_student >= 3.6 && mean_student <= 3.8); parray::iterator end = remove_greater(m.begin(), m.end(), 3); double mean2 = mean_mark(m.begin(), end); assert (mean2 >= 0.9 && mean2 <= 1.1); #endif } { vector> m; m.push_back(shared_ptr(new Student(2))); m.push_back(shared_ptr(new Pupil(1))); m.push_back(shared_ptr(new Student(5))); m.push_back(shared_ptr(new Student(4))); m.push_back(shared_ptr(new Person())); #ifdef SOLVED_3 double mean = mean_mark(m.begin(), m.end()); assert (mean >= 2.3 && mean <= 2.5); double mean_student = mean_mark_student(m.begin(), m.end()); assert (mean_student >= 3.6 && mean_student <= 3.8); assert(m.size() == 5); m.erase(remove_greater(m.begin(), m.end(), 3), m.end()); assert(m.size() == 3); double mean2 = mean_mark(m.begin(), m.end()); assert (mean2 >= 0.9 && mean2 <= 1.1); #endif } } /* vim: set et sw=2 ts=2: */