Zapoctovy test 27.1.2016, 14:00

Základní kurs objektově orientovaného programování v C++. Třídy a objekty, zapouzdření, metody, plymorfismus. Abstraktní datové typy, přetěžování. Kontejnery, iterátory, algoritmy. Šablony, generické programování, kompilační polymorfismus. Výjimky. Bezpečné a přenositelné programování, vazby na OS.
bombur

Zapoctovy test 27.1.2016, 14:00

Příspěvek od bombur »

Tema: polymorfni binarni operace

Zadani: Chceme mit datovou strukturu, do ktere by bylo mozne vkladat polozky typu int, double, std::string. Soucasne bychom chteli, aby se polozky teto datove struktury daly scitat. Scitani ma byt realizovano nasledovne:
  • int + int = int (proste secteni)
  • int + double = double (proste secteni)
  • int + string = string (int prevedeme na string a zretezime)
  • double + double = double (proste secteni)
  • double + string = string (double prevedeme na string a zretezime)
  • string + string = string (zretezeni)
Ukolem je implementovat metodu add tak, aby provadela vyse uvedene scitani (pojmenovani neni podstatne, mohli jsme implementovat jako operator+ nebo jakkoli obdobne). Implementace by mela podporovat nasledujici kod:

Kód: Vybrat vše

std::vector< NECO > v; // zvolena datova struktura pro ulohu neni podstatna, zde je to std::vector
v.push_back( NECO( 1 ) );
v.push_back( NECO( 3.14 ) );
v.push_back( NECO( "ahoj" ) );
v.push_back( add( v[0], v[1] ) ); // melo by do vectoru vlozit 4.14
v.push_back( add( v[2], v[3] ) ); // melo by do vectoru vlozit "ahoj4.14"
Za NECO muzeme dosadit cokoli potrebujeme (metodu, tridu, nic, cokoli) a za kazde NECO muzeme dosadit neco jineho (tj. za prvni NECO klidne muzeme dosadit neco jineho nez za druhe NECO).

Za reseni nebyla nepovazovana implementace tridy, ktera v sobe ma napriklad enum a na pozadani sdeli: "jsem integer", "jsem double" anebo "jsem string" ci jakakoli jina obdobna reseni.
Bylo zmineno, abychom si dali pozor na komutativitu (posledni radek kodu nevlozi "4.14ahoj", ale "ahoj4.14").
Program nema zadny interface s okolim, jde pouze o reseni daneho problemu.

Poznamky:
  • Zadaval dr. Zavoral.
  • Internet zapnuty, byly povoleny pouze reference jazyka + slidy z prednasky.
  • 20 minut probihalo zadavani. Na reseni byl casovy limit 3 hodiny (nevim, zda se prodluzovalo). Odchazel jsem za hodinu a ctvrt jako druhy, uspesnost nevim.
  • Reseni mi dr. Zavoral prohlizel pomerne podrobne, objevil mi nektere nedostatky, ktere jsem musel opravit.
Reseni:
Uloha byla na virtualni funkce, polymorfismus. Zde je me reseni (predem upozornuji, ze se nejdena o zadne elegantni nebo krasne reseni, snazil jsem ulohu vyresit co nejdrive a spravne):

Kód: Vybrat vše

#include <string>
#include <iostream>
#include <vector>

using namespace std;

class general {
public:
	virtual general* sum_with_general(general* g) const = 0; // rozpozna se, co jsem zac ja

	virtual general* add_to_given_as_right_operand(int value) const = 0; // rozpozna se, co je zac druhy parametr add(...)
	virtual general* add_to_given_as_right_operand(double value) const = 0; // rozpozna se, co je zac druhy parametr add(...)
	virtual general* add_to_given_as_right_operand(const string& value) const = 0; // rozpozna se, co je zac druhy parametr add(...)

	virtual void print() const = 0;
};

class String : public general {
public:
	string value;

	String(const string& value) : value(value) { }

	virtual general* sum_with_general(general* g) const { // g bude povazovan za pravy operand
		return g->add_to_given_as_right_operand(value);
	}

	virtual general* add_to_given_as_right_operand(int i) const {
		string i_as_string = to_string(i);
		return new String(i_as_string + value);
	}

	virtual general* add_to_given_as_right_operand(double d) const {
		string d_as_string = to_string(d);
		return new String(d_as_string + value);
	}

	virtual general* add_to_given_as_right_operand(const string& s) const {
		return new String(s + value);
	}

	virtual void print() const {
		cout << "String=" << value << endl;
	}
};

class Double : public general {
public:
	double value;

	Double(double value) : value(value) { }

	virtual general* sum_with_general(general* g) const { // g bude povazovan za pravy operand
		return g->add_to_given_as_right_operand(value);
	}

	virtual general* add_to_given_as_right_operand(int i) const {
		return new Double(static_cast<double>(i) + value);
	}

	virtual general* add_to_given_as_right_operand(double d) const {
		return new Double(d + value);
	}

	virtual general* add_to_given_as_right_operand(const string& s) const {
		string value_as_string = to_string(value);
		return new String(s + value_as_string);
	}

	virtual void print() const {
		cout << "Double=" << value << endl;
	}
};

class Integer : public general {
public:
	int value;

	Integer(int value) : value(value) { }

	virtual general* sum_with_general(general* g) const { // g bude povazovan za pravy operand
		return g->add_to_given_as_right_operand(value);
	}

	virtual general* add_to_given_as_right_operand(int i) const {
		return new Integer(i + value);
	}

	virtual general* add_to_given_as_right_operand(double d) const {
		return new Double(d + static_cast<double>(value));
	}

	virtual general* add_to_given_as_right_operand(const string& s) const {
		string value_as_string = to_string(value);
		return new String(s + value_as_string);
	}

	virtual void print() const {
		cout << "Integer=" << value << endl;
	}
};

general* add(general* a, general* b) {
	// mame provest a + b
	general* sum = a->sum_with_general(b);

	return sum;
}

using general_ptr = general*;
int main(int argc, char** argv) {
	// test ze zadani
	vector<general_ptr> v;
	v.push_back(new Integer(1));
	v.push_back(new Double(3.14));
	v.push_back(new String("ahoj"));
	v.push_back(add(v[0], v[1]));
	v.push_back(add(v[2], v[3]));

	// vypis vysledku
	for (auto i = v.begin(); i != v.end(); ++i) {
		(*i)->print();
	}

	// delete
	for (auto i = v.begin(); i != v.end(); ++i) {
		delete *i;
	}
	v.clear();

	return 0;
}
Odpovědět

Zpět na „NPRG041 Programování v C++“