Fahrzeuge 3: unique pointer
main_try.cpp
Go to the documentation of this file.
1 // C++ Vorlesung 8. Juni 2018
2 // Klassenhierarche mit virtuellen Methoden
3 // Nutzung des Polymorphismus via unique_ptr
4 // STL: sorting and accumulate as examples
5 // !! now we have a
6 
7 // 10c --> 10c_unique: use unique_ptr instead of C-pointer
8 // fahrzeug.cpp, fahrzeug.h are mostly unchanged. Changes regarding warning messages from compilers etc.
9 
10 /*
11  g++ -pedantic -std=c++14 -Weffc++ -Wall -Wextra -pedantic -Wswitch-default -Wfloat-equal -Wundef -Wredundant-decls -Winit-self -Wshadow -Wparentheses -Wshadow -Wunreachable-code -Wuninitialized -Wmaybe-uninitialized *.cpp
12  cppcheck --enable=all --inconclusive --std=c++14 --std=posix --suppress=missingIncludeSystem *.cpp
13  clang++ -std=c++14 -fsyntax-only -Wdocumentation -Wconversion -Wshadow -Wfloat-conversion -pedantic *.cpp
14  clang++ -std=c++14 -Weverything -Wno-c++98-compat -Wno-padded *.cpp
15  clang++ -cc1 --help
16  icpc -std=c++14 -Wall -Wextra -pedantic *.cpp
17 */
18 
19 #include <iostream>
20 #include <vector>
21 #include <algorithm>
22 #include <memory> // unique_ptr
23 #include <numeric> // accumulate
24 #include <typeinfo>
25 #include "fahrzeug.h"
26 using namespace std;
27 
33 ostream& operator<<(ostream &s, const Fahrzeug& p);
34 
40 ostream& operator<<(ostream &s, const vector<unique_ptr<Fahrzeug>>& v);
41 
49 bool fuel_consumption(const unique_ptr<Fahrzeug>& a, const unique_ptr<Fahrzeug>& b);
50 
51 bool fuel_consumption(const unique_ptr<Fahrzeug>& a, const unique_ptr<Fahrzeug>& b)
52 {
53  return a->verbrauch() < b->verbrauch();
54 }
55 
63 float add_fuel(float x, const unique_ptr<Fahrzeug>& y);
64 
65 float add_fuel(float x, const unique_ptr<Fahrzeug>& y)
66 {
67  return x + y->verbrauch();
68 }
69 
70 int main()
71 {
72  cout << " -------- New in v_10c_unique --------------\n";
73  // new in v_10c
74  // container of base class pointers
75  vector<unique_ptr<Fahrzeug>> v;
76  // push_back and unique_ptr, see: http://stackoverflow.com/questions/3283778/why-can-i-not-push-back-a-unique-ptr-into-a-vector
77  // |-- we need a pointer to an instance
78  v.push_back( unique_ptr<Fahrzeug> (new Raba(3600, 4000)) );
79  v.push_back( unique_ptr<Fahrzeug> (new Opel(1450)) );
80  v.push_back( unique_ptr<Fahrzeug> (new MAN(1200, 12000)) );
81  v.push_back( unique_ptr<Fahrzeug> (new Smart(950)) );
82  v.push_back( unique_ptr<Fahrzeug> (new Smart(1100)) );
83 
84 
85 // C++-14
86 // https://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique
87  vector<unique_ptr<Fahrzeug>> w
88  {
89  make_unique<Fahrzeug> (Raba(3600, 4000)) // doesn't work
90  };
91 
92  auto ip = make_unique<Raba>(Raba(3600, 4000));
93 
94 
95  cout << v << endl;
96 
97  cout << " -------- after sort (standard --> incorrect) -------------\n";
98  sort(v.begin(),v.end());
99  cout << v << endl;
100 
101  cout << " -------- only the pointers have been compared -------------\n";
102 
103  cout << " -------- after sort (compare regarding fuel consumption) -------------\n";
104  sort(v.begin(),v.end(), fuel_consumption );
105  cout << v << endl;
106 
107  cout << " -------- correct-------------\n";
108 
109  // Berechne Flottenverbrauch (gleich gewichtet)
110  // konventionell
111  float sum=0.0;
112  for (unsigned int i=0; i<v.size(); ++i)
113  {
114  sum += v[i]->verbrauch();
115  }
116  cout << "konv: durchschnittlicher Verbrauch: " << sum/v.size() << endl;
117 
118  // via STL
119  float sum2 =accumulate(v.begin(), v.end(), 0.0f, add_fuel);
120  cout << "accu: durchschnittlicher Verbrauch: " << sum2/v.size() << endl;
121 
122 
123  cout << " -------- sort using lambda function for 'operator>' -------------\n";
124 // Sorting by using lambda-functions (ascending order wrt. fuel)
125 // http://stackoverflow.com/questions/5122804/sorting-with-lambda
126  sort(v.begin(),v.end(),
127  [](const unique_ptr<Fahrzeug>& aa, const unique_ptr<Fahrzeug>& cc) -> bool
128  {
129  return aa->verbrauch() > cc->verbrauch();
130  }
131  );
132 
133  cout << v << endl;
135  return 0;
136 } // free the memory storing the pointers in vector 'v' at the end of the scope
137 
138 
139 // We define an output function for references to the basis class
140 // |--- parameter passing by reference allows polymorphism
141 ostream& operator<<(ostream &s, const Fahrzeug& p)
142 {
143 // Virtual Method Table
144 // |-- VMT at run time ==> method from derived class
145 // | |--- always non-virtual method from base class
146  s << p.classname() << " : " << p.Get_kg() << " kg and "
147 // |-- VMT at run time ==> method from derived class
148  << p.verbrauch() << " l/100km" << endl;
149  return s;
150 }
151 
152 
153 ostream& operator<<(ostream &s, const vector<unique_ptr<Fahrzeug>>& v)
154 {
155  for (const auto& it: v) // Reference is required with unique_ptr. No copy constructor for unique_ptr available!
156  {
157  cout << *it;
158  };
159  return s;
160 }
virtual float verbrauch() const =0
virtual std::string classname() const
Class name.
Definition: fahrzeug.h:27
int Get_kg() const
Definition: fahrzeug.h:19
Definition: fahrzeug.h:105
Definition: fahrzeug.h:156
Definition: fahrzeug.h:130
float add_fuel(float x, const unique_ptr< Fahrzeug > &y)
Adds the fuel consumption of a vehicle y to quantity x.
Definition: main_try.cpp:65
bool fuel_consumption(const unique_ptr< Fahrzeug > &a, const unique_ptr< Fahrzeug > &b)
Compares the fuel consumption between two vehicles.
Definition: main_try.cpp:51
ostream & operator<<(ostream &s, const Fahrzeug &p)
Prints some info from a vehicle.
Definition: main_try.cpp:141
int main()
Definition: main_try.cpp:70