Kody programów [ZTP]

Kody programów demonstrowanych na wykładzie:

Wyjątki

Program #1

Podgladanie.h


#pragma once
#include <iostream>

using namespace std;

class Podgladanie
{
public:
	Podgladanie(void) { 
		cout << "Podgladanie()"<< endl; 
	};
	~Podgladanie(void) { 
		cout << "~Podgladanie()"<< endl;
	};
};

main.cpp


#include <iostream>
#include "Podgladanie.h"

using namespace std;

void przezDziurkeOdKlucza() {
 Podgladanie P;
  for(int i = 0; i < 3; i++)
   cout <<"Nic nie widzę."<< endl;
  throw 47;
}

int main() {
 try {
  cout << "I co? widzisz coś?..." << endl;
  przezDziurkeOdKlucza();
 } catch(int) {
  cout << "To daj też popatrzeć." << endl;
 }
 return 0;
}

Program #2


#include <iostream>

using namespace std;

class Brzoskwinia {
public:
  class Pestka {};
  class Mala : public Pestka {};
  class Duza : public Pestka {};
  void scisk() { throw Duza(); }
};

int main() {
  Brzoskwinia b;
  try {
    b.scisk();
  } 
  catch(Brzoskwinia::Mala&) {	// nigdy nie zostanie wywołany..
    cout << "Mala Pestka schwytana" << endl;
  } 
  catch(Brzoskwinia::Duza&) {	// .. a ten tak.
    cout << "Duza Pestka schwytana" << endl;
  }
  catch (Brzoskwinia::Pestka&) { // ten jest tylko pro forma.
	  cout << "zlapalem, co akurat lecialo.." << endl;
  };
  return 0;
}

Program #3


#include<exception>
#include<iostream>

using namespace std;

void nowe_zakonczenie( ) {	
  cout << "Ja tu wroce.." << endl;
  exit(0);
};
void (*wf)() = set_terminate(nowe_zakonczenie);

class Fuszerka {
public:
  class Owoc {};
  void f() {
    cout << "Fuszerka ::f()" << endl;
    throw Owoc();
  };
  Fuszerka() { };
  ~Fuszerka() { 
	  throw 'c'; 
  };
};

int main() {
  try {
    Fuszerka b;
    b.f();
  } catch(...) {
    cout << "zlapalem cos.." << endl;
  }
  return 0;
}

Program #4


#include<exception>
#include<iostream>

using namespace std;

class Trace {
  static int counter;
  int objid;
public:
  Trace() {
    objid = counter++;
    cout << "konstruktor Trace #" << objid << endl;
    if(objid == 3) throw 3;
  }
  ~Trace() {
    cout << "destruktor Trace #" << objid << endl;
  }
};

int Trace::counter = 0;
int main() {
  try {
    Trace array[5];
} catch(int i) {
    cout << "przechwycono " << i << endl;
  }
  return 0;
}

Program #5


#include <cstdio>
#include<cstring>
#include <iostream>

using namespace std;

class mem
{
	char * pdata;
public: 
	mem(unsigned int size=0); 
	~mem() { delete [] pdata; }
	void alloc(unsigned int size);
	char* getbuffer() const { return pdata; };
};
mem::mem(unsigned int size)
{
	if (size)
		pdata = new char[size];
	else pdata=0;
};
void mem::alloc(unsigned int size)
{
	if (pdata) 
		return;
	pdata = new char[size];
};

int main() {
	mem bufor(100);
	strcpy(bufor.getbuffer(),"Taki sobie napis");
	cout << bufor.getbuffer() << endl;	
	return 0;
}

Cechy charakterystyczne


#include<iostream>

using namespace std;

class Milk {
public:
	friend ostream& operator<<(ostream& os, const Milk&) {
		return os << "Mleko";
	}
};
class CondensedMilk {
public:
	friend ostream&  operator<<(ostream& os, const CondensedMilk &) {
		return os << "Skondensowane Mleko";
	}
};
class Honey {
public:
	friend ostream& operator<<(ostream& os, const Honey&) {
		return os << "Miodek";
	}
};
class Cookies {
public:
	friend ostream& operator<<(ostream& os, const Cookies&) {
		return os << "Ciasteczka";
	}
};

class Bear {
public:
	friend ostream& operator<<(ostream& os, const Bear&) {
		return os << "Puchatek";
	}
};

class Boy {
public:
	friend ostream& operator<<(ostream& os, const Boy&) {
		return os << "Krzyś";
	}
};

// bazowy szablon cech (pusty, może opisywać cechy wspólne)
template<class Guest>
class GuestTraits { };


// Cechy charakterystyczne – specjalizacje typu Guest:
// Specjalizacja dla misia
template<> class GuestTraits<Bear> {
public:
	typedef CondensedMilk beverage_type;
	typedef Honey snack_type;
};
// specjalizacja dla chłopca
template<> class GuestTraits<Boy> {
public:
	typedef Milk beverage_type;
	typedef Cookies snack_type;
};
// specjalizacja mieszana
class MixedUpTraits {
public:
	typedef Milk beverage_type;
	typedef Honey snack_type;
};

// Szablon Guest – korzysta z klasy cech
template<class Guest, class traits = GuestTraits<Guest> >
class BearCorner {
	Guest theGuest;
	typedef typename traits::beverage_type beverage_type;
	typedef typename traits::snack_type snack_type;
	beverage_type bev;
	snack_type snack;

public:
	BearCorner(const Guest& g) : theGuest(g) {}
	void entertain() {
		cout << "Wchodzi " << theGuest
			<< " podajemy " << bev
			<< " i " << snack << endl;
	}
};

int main() {
	Boy cr;
	BearCorner<Boy> pc1(cr);
	pc1.entertain();
	Bear pb;
	BearCorner<Bear> pc2(pb);
	pc2.entertain();
	BearCorner<Bear, MixedUpTraits> pc3(pb);
	pc3.entertain();
}

Domieszkowanie klas


#include <string>
#include <ctime>
#include <iostream>

using namespace std;

// klasa reprezentująca prosty stoper
class Timer {
	time_t   start, finish;
public:
	Timer()	{
		Reset();
	}
	double GetElapsedTimeSecs()	{
		time(&finish);
		return difftime(finish, start);
	}
	void Reset() {
		time(&start);

	}
};

// Domieszka #1: Zapisywanie komunikatów o rozpoczęciu i zakończeniu zadania
template< class T >
class LoggingTask : public T {
public:
	void Execute() {
		std::cout << "LOG: The task is starting - " <<
                     GetName().c_str() << std::endl;
		T::Execute();
		std::cout << "LOG: The task has completed - " <<
                     GetName().c_str() << std::endl;
	}
};
// Domieszka #2: Zapisywanie czasu wykonania zadania
template< class T >
class TimingTask : public T
{
	Timer timer_;
public:
	void Execute() {
		timer_.Reset();
		T::Execute();
		double t = timer_.GetElapsedTimeSecs();
		std::cout << "Task Duration: " << t << " seconds" << std::endl;
	}
};
// Klasa implementująca właściwą czynność realizowaną przez to zadanie
class MyTask {
public:
	virtual void Execute() {
		std::cout << "...This is where the task is executed..." << std::endl;
		// ... wykonanie zadania
	}
	virtual std::string GetName() {
		return "My task name";
	}
};
/*
Klasy TimingTask oraz LoggingTask są klasami - domieszkami.
Klasa MyTask reprezentuje jedno konkretne zadanie (w przeciwieństwie do domieszek, które
mają charakter uniwersalny, ponieważ muszą znaleźć zastosowanie w wielu miejscach kodu).
*/
// korzystanie z klas
int main() {
	MyTask t1; // Obiekt reprezentujący zadanie
	t1.Execute();
	TimingTask< MyTask > t2; // Obiekt reprezentujący zadanie domieszkowane pomiarem czasu
	t2.Execute();
	LoggingTask< TimingTask< MyTask > > t3; // Obiekt reprezentujący zadanie domieszkowane logowaniem i pomiarem czasu
	t3.Execute();

	// Obiekt reprezentujący zadanie domieszkowane pomiarem czasu i logowaniem
	typedef TimingTask<LoggingTask<MyTask>> Task;
	Task t4;
	t4.Execute();
}

STL – kontenery

Iteratory i wskaźnik względny do metody


#include <vector>
#include <iostream>

using namespace std;

class Z {
	int i;
public:
	Z(int ii) : i(ii) {}
	void g() { ++i; }
	friend ostream& operator<<(
		ostream& os, const Z& z);
};

ostream& operator<<(ostream& os, const Z& z) {
	return os << z.i;
}

template<typename Cont, typename PtrMemFun>
	void apply(Cont& c, PtrMemFun f) {
	typename Cont::iterator it = c.begin();
	while (it != c.end()) {
		((*it).*f)();
		++it;
	}
}

//Przykład zastosowania "apply"
int main() {
	vector<Z> vz;
	// zapełniamy wektor
	for (int i = 0; i < 10; i++)
		vz.push_back(Z(i));

	// wysyłamy wektor do strumienia cout
	for (vector<Z>::iterator j = vz.begin(); j != vz.end(); ++j) 
		cout << *j << " ";
	cout << endl;

	// wykorzystujemy szablon apply
	apply(vz, &Z::g);

	// ponownie wysyłamy wektor do cout
	for (vector<Z>::iterator j = vz.begin(); j != vz.end(); ++j) 
		cout << *j << " ";
	cout << endl;

	system("pause");
}

vector – przykład użycia #2

FileEditor.h


#pragma once
#include <vector>
#include <string>
#include <iostream>

using namespace std;

class FileEditor: public vector<std::string>
{
public:
	void open(const char* filename);
	FileEditor(const char* filename) {
		open(filename);
	};
	FileEditor() {};
	void write(ostream& out = cout);
};

FileEditor.cpp


#include "FileEditor.h"
#include <fstream>

void FileEditor::open(const char* filename) {
	ifstream in(filename);
	string line;
	while (getline(in, line))
		push_back(line);
}

void FileEditor::write(ostream& out) {
	for (iterator w = begin(); w != end(); w++)
		out << *w << endl;
}

main.cpp


#include "FileEditor.h"
#include <sstream>

using namespace std;

int main(int argc, char* argv[]) {
	FileEditor file;
	if (argc > 1) {
		file.open(argv[1]);
	}
	else {
		file.open("plik-testowy.txt");
	}
	int i = 1;
	FileEditor::iterator w = file.begin();
	while (w != file.end()) {
		ostringstream ss;
		ss << i++;
		*w = ss.str() + ": " + *w; // dopisanie numeru na początku wiersza
		++w;
	}
	file.write(cout);
	system("pause");
}

map – przykład użycia


#include <map>
#include <iostream>
#include <string>

using namespace std;

class Student {
	string Nazwisko;
	int Wiek;
public:
	Student() : Nazwisko("Nowy student"), Wiek(19) {};
	Student(const string& nazwisko, const int wiek) :
		Nazwisko(nazwisko), Wiek(wiek) {};
	Student(const Student& temp) :
		Nazwisko(temp.PobierzNazwisko()), Wiek(temp.PobierzWiek()) {};
	~Student() {};
	void UstawNazwisko(const string& nazwisko) { Nazwisko = nazwisko; };
	string PobierzNazwisko() const { return Nazwisko; };
	void UstawWiek(const int wiek) { Wiek = wiek; };
	int PobierzWiek() const { return Wiek; };
	Student& operator=(const Student& temp);
};
Student& Student::operator=(const Student& temp) {
	Nazwisko = temp.PobierzNazwisko();
	Wiek = temp.PobierzWiek();
	return *this;
};
ostream& operator<<(ostream& osoba, const Student& temp) {
	osoba << temp.PobierzNazwisko() << " ma " << temp.PobierzWiek() << " lat";
	return osoba;
};
template<typename T, typename A>
void ShowMap(const map<T, A>& v) {
	for (typename map<T, A>::const_iterator i = v.begin(); i != v.end(); ++i)
		cout << i->first << ": " << i->second << "\n";
	cout << endl;
};
typedef map<string, Student> Studenci; //Studenci – mapa elementów
int main() {
	Student Kowalski("Kowalski", 19);
	Student Nowak("Nowak", 20);
	Student Adamczewski("Adamczewski", 21);
	Student Kowalczyk("Kowalczyk", 16);
	Studenci Rocznik;
	// dodajemy nowe elementy i nadajemy im wartości
	Rocznik[Kowalski.PobierzNazwisko()] = Kowalski;
	Rocznik[Nowak.PobierzNazwisko()] = Nowak;
	Rocznik[Adamczewski.PobierzNazwisko()] = Adamczewski;
	Rocznik[Kowalczyk.PobierzNazwisko()] = Kowalczyk;
	cout << "Rocznik:\n";
	ShowMap(Rocznik);
	// próba odwołania się do nieistniejącego klucza bez przypisania wartości
	cout << "Wiemy że " << Rocznik["Zeromski"].PobierzNazwisko()
		<< " ma " << Rocznik["Zeromski"].PobierzWiek() << " lat\n";
	system("pause");
};