Typdefinitionen
Diese Lektion enthält Notizen für den Dozenten, sie ist aber noch nicht so ausformuliert, daß sie im Selbststudium gelesen werden kann.
- Was mit einer ganz leeren Klasse „class C {}“ geht (Erzeugung, Zuweisung, sizeof)
#include <iostream>
#include <ostream>
struct pair
{
pair() : first{ 1 }, second{ 2 } {}
pair( int const first, int const second ):
first{ first }, second{ second } {}
int first;
int second;
int summe() const { return first + second; } };
int main()
{ pair x;
pair y{ 3, 7 };
x.first = 10;
x.second = 20;
::std::cout << x.first << '\n';
::std::cout << x.second << '\n';
::std::cout << y.first << '\n';
::std::cout << y.second << '\n';
::std::cout << x.summe() << '\n';
::std::cout << y.summe() << '\n';
}
Sobald in der Klassendefinition ein Konstruktor deklariert wurde, werden keine Konstruktoren mehr stillschweigend hinzugefügt.
======================================================================
#include <iostream>
#include <ostream>
class pair
{
int first;
int second;
public:
pair() : first{ 1 }, second{ 2 } {}
pair( int const first, int const second ):
first{ first }, second{ second } {}
int summe() const { return first + second; }; };
int main()
{ pair x;
pair y{ 3, 7 };
::std::cout << x.summe() << '\n';
::std::cout << y.summe() << '\n';
}
Anwendungsbeispiel einer vollständigeren Klasse
#include <iostream>
#include <ostream>class pair
{ double x, y;
public:
pair( double const x = 0, double const y = 0 ): x{ x }, y{ y } {}
pair & operator ++() { ++x; return *this; }
pair operator ++( int ) { auto result = *this; ++*this; return result; }
pair & operator +=( const pair & o ){ x += o.x; y += o.y; return *this; }
::std::ostream & print( ::std::ostream & stream ) const
{ return stream << '<' << x << ", " << y << '>'; }};inline pair operator +( pair result, pair const & other )
{ result += other; return result; }inline ::std::ostream& operator <<( ::std::ostream & stream, pair const & object )
{ return object.print( stream ); }int main(){ pair const c; ::std::cout << c << '\n'; }
Anwendungsbeispiel Spionagetechniken
Wir sehen, daß ein temporäres Objekt sofort wieder aufgelöst wird.
#include <initializer_list>
#include <iostream>
#include <ostream>
struct array
{ array( ::std::initializer_list< int >const ){};
~array(){ ::std::cout << "I, temporary array, destroyed\n"; } };
int * begin( array ){ return nullptr; }
int main()
{ ::std::cout << "before\n";
const int * y = begin( { 1, 2, 3 });
::std::cout << "after\n";
::std::cout << "y = " << y << '\n'; }
before
I, temporary array, destroyed
after
y = 0
Übungsaufgaben
Definieren Sie eine Art von „Kontoklasse“ mit einem „getter“, einem „setter“ und einem „adder“, sowie einer Elementfunktion »transfer«.
Definieren Sie eine Stack-Klasse für Strings mit den Operationen push und pop.
main.cpp
#include <initializer_list>
#include <chrono>
#include <functional>#include <iostream>
#include <vector>
#include <unordered_set>
#include <set>
#include <algorithm>
#include <climits>
#include <cstdlib>
#include <string>
#include <iomanip>
#include <ios>
#include <random>
using namespace ::std::literals;
static void escape( volatile void * p )
{ asm volatile( "" : : "g"(p) : "memory" ); }static void escape( void * p ) /* by Chandler Carruth */
{ asm volatile( "" : : "g"(p) : "memory" ); }/* todo: split in privacy and actual format */
template< typename T >
::std::string format( T value )
{ double privacy_factor = 1.0; /* default: 1.0 */
double privacy_noise = 0.0; /* default: 0.0 */
::std::string s; int i = 0; int n = 0;
long double v = value;
v = v * privacy_factor;
v = v *( 1.0 + privacy_noise * ( rand() /( 1.0 + RAND_MAX )- 0.5 ));
value = v;
if( value )
while( value )
{ if( i &&( i % 3 == 0 ))
{ s = " .,';:-=%#$"[ i/3 ] + s; ++n; }
/* above there is a bug: i/3 might be larger than the string */
++i; ++n;
s = "0123456789"[ value % 10 ] + s;
value /= 10; }
else s = "0";
while( n++ < 20 )s = " " + s;
return s; }struct timer
{ using timepoint = ::std::chrono::high_resolution_clock::time_point;::timer::timepoint t1;
::timer::timepoint t2;
decltype( ::timer::t2 - ::timer::t1 )sum{};timer(){ this->reset(); }
void reset()
{ this->t1 = ::std::chrono::high_resolution_clock::now();
this->t2 = t1;
sum = t2 - t1; }void print( ::std::string const s, int const text_width, int const number_width )
{ this->t2 = ::std::chrono::high_resolution_clock::now();
this->sum += this->t2 - this->t1;
::std::cout << ::std::setw( text_width )<< ::std::left << s << ::std::setw( number_width )<< ::std::right << format(( sum ).count()) << '\n'; }};template <class T>
struct sorted_vector
{ ::std::vector< T >vector;
using iterator = typename ::std::vector< T >::iterator ;
using const_iterator = typename ::std::vector< T >::const_iterator ;
iterator begin() { return vector.begin(); }
iterator end() { return vector.end(); }
const_iterator begin() const { return vector.begin(); }
const_iterator end() const { return vector.end(); }
explicit sorted_vector(): vector{} { }
iterator insert( const T & t )
{ iterator i = lower_bound( begin(), end(), t );
if( i == end() || t < *i )
{ vector.insert( i, t ); }
return i; }const_iterator find( const T& t ) const
{ const_iterator i = lower_bound( begin(), end(), t );
return i == end() || t < *i ? end() : i; }};auto const seed
{ ::std::chrono::system_clock::now().time_since_epoch().count() };auto linear_congruential_engine
{ ::std::linear_congruential_engine< unsigned long, 40014uL,0uL,2147483563uL >( seed ) };auto dice_distribution
{ ::std::uniform_int_distribution< unsigned long >{ 0, ULONG_MAX }};void randomize( unsigned long const value )
{ linear_congruential_engine.seed( value ); }unsigned long dice()
{ return dice_distribution( linear_congruential_engine ); }template< typename T >
static inline void fill( T & container )
{ ::randomize( 0 );
for( unsigned long l = 0; l < 1'000'000; ++l )container.insert( dice() );
escape( &container ); }template< typename T >
static inline void retrieve( T const & container )
{ typename T::const_iterator const e = container.end();
int i = 0;
::randomize( 0 );
for( unsigned long l = 0; l < 1'000'000; ++l )i = i+( e == container.find( dice() ));::std::cout << "size = " << container.vector.size() << '\n';
escape( &i ); }template< typename T >
static inline void measure( ::std::string const name, int const text_width, int const number_width )
{ ::timer timer;T container;
timer.reset();
fill( container );
timer.print( "filling "s + name, text_width, number_width );
timer.reset(); retrieve( container ); timer.print( "retrieving "s + name, text_width, number_width ); }
void measurement()
{ int const text_width = 32; int const number_width = 14;
measure< ::sorted_vector< unsigned long >>( "::sorted_vector", text_width, number_width );
// measure< ::std::unordered_set< unsigned long >>( "::std::unordered_set", text_width, number_width );
// measure< ::std::set< unsigned long >>( "::std::set", text_width, number_width );
::std::cout << '\n'; }
int main()
{ for( int i = 0; i < 1; ++i )measurement(); }