Commit 786e305a by Szeberényi Imre

V0

parents
# Pelda Makefile a diamond orokls feladat megoldasahoz
# Solaris (ural2) es Linux ala.
# forditando obj. fajlok
objs = diamond.o
prog = diamond # a program neve
CXX = g++ # a C++ fordito neve
CXXFLAGS = -pedantic -Wall # C++ kapcsolok: legyen bobeszedu,
CXXFLAGS += -g # ... es forduljon debug info is
# alapertelmezett cel: tesztprogram linkelese
all: $(prog)
$(prog): $(objs)
$(CXX) $(objs) -o $@
$(objs):
# takaritas igeny szerint
clean:
rm -f $(objs) $(prog)
/**
* \file alkalmazott.h
* Alkalmazott alaposztály deklarációja
* Az egyszerűség kedvéért minden tagfüggvényt inline valósítottunk meg.
*
*/
#ifndef ALKALMAZOTT_H
#define ALKALMAZOTT_H
#include <iostream>
#include <string>
#include "memtrace.h"
/// header fájlban ne használjon using direktívát, mert a hatása
/// rejtve marad
/**
* Alkalmazott
*/
class Alkalmazott {
std::string nev; // nev
double fizetes; // fizetés
public:
Alkalmazott() :fizetes(0) {
std::cout << "Baj van: Az Alkalmazott default konstruktora hivodott!" << std::endl
<< " Javitsa a kodot!" << std::endl;
}
Alkalmazott(const std::string& n, double fiz) :nev(n), fizetes(fiz) {
#if TESTLEVEL <= 1
std::cout << 'A';
#endif
}
/// Név lekérdezése
/// @return - nev
const std::string& getNev() const { return nev; }
/// Fizetés lekérdezése
/// @return - fizetés
double getFiz() const { return fizetes; }
/// Név beállítása
/// @param nev - név
void setNev(const std::string& n) { nev = n; }
/// Fizetés beállítása
/// @param fiz - fizetés
void setFiz(double fiz) { fizetes = fiz; }
/// Adatok kiírása
/// @param os - output adatfolyam
virtual void kiir(std::ostream& os = std::cout) const {
os << nev << " fizetese: " << fizetes << std::endl;
}
virtual ~Alkalmazott() {
#if TESTLEVEL <= 1
std::cout << "Megszunik: ";
kiir(std::cout);
#endif
}
};
#endif // ALKALMAZOTT_H
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="6" />
<Project>
<Option title="diamond_test" />
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="Debug">
<Option output="bin/Debug/diamond" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Debug/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-g" />
<Add option="-DMEMTRACE" />
</Compiler>
</Target>
<Target title="Release">
<Option output="bin/Release/diamond" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Release/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-O2" />
</Compiler>
<Linker>
<Add option="-s" />
</Linker>
</Target>
</Build>
<Compiler>
<Add option="-pedantic-errors" />
<Add option="-pedantic" />
<Add option="-Wall" />
</Compiler>
<Unit filename="alkalmazott.h" />
<Unit filename="diamond_test.cpp" />
<Unit filename="elkeszult.h" />
<Unit filename="iroda.h" />
<Unit filename="irodistak.h" />
<Unit filename="memtrace.cpp" />
<Unit filename="memtrace.h" />
<Unit filename="palkalmazott.h" />
<Unit filename="perz_test.cpp" />
<Unit filename="pirodistak.h" />
<Unit filename="serializable.h" />
<Extensions>
<code_completion />
<debugger />
<envvars />
<DoxyBlocks>
<comment_style block="0" line="0" />
<doxyfile_project />
<doxyfile_build />
<doxyfile_warnings />
<doxyfile_output />
<doxyfile_dot />
<general />
</DoxyBlocks>
</Extensions>
</Project>
</CodeBlocks_project_file>
/**
* \file diamond_test.cpp
* Egyszerű program a rombusz (diamond) öröklés problémának bemutatására
*
*/
#include "elkeszult.h"
/**
* Feladatok:
* 1. Értse meg a programot, majd szüntesse meg a rombusz öröklésből
* származó adattöbbszörözést!
* 2. Az Iroda osztály az std::vector osztályt használja tárolásra.
* A tarolo_tipus módosításával ez könnyen lecserélhető pl. std::list,
* vagy std::deque osztályra. Miért?
* 3. Cserélje le először listára, majd sorra!
* 4. Készítse ez irodistak perzisztens változatát a pirodistak.h- fájlban
*
*
*/
/// Ellenőrizzük, hogy az elkeszult.h-ban definiálta-e az ELKESZULT makrót
#ifndef ELKESZULT
#define ELKESZULT 0 /// ha mégse definiálta
#endif
#if ELKESZULT < 0 /// ha hibásan definiálta
#undef ELKESZULT
#define ELKESZULT 0
#endif
/// ------- Ellenőrző rész vége ----------
#include <iostream>
#include "iroda.h"
#include "alkalmazott.h"
#include "irodistak.h"
#include "memtrace.h"
#include "gtest_lite.h"
using std::cin;
using std::cout;
using std::endl;
int main() {
GTINIT(std::cin); // Csak C(J)PORTA működéséhez kell
try {
Iroda munkahely;
munkahely.felvesz(new Alkalmazott("Lusta Dick", 100)); // 1. obj létrehozása
munkahely.felvesz(new HatIdeju("Grabovszki", 300, 1000)); // 2. obj
munkahely.felvesz(new CsopVez("Mr. Gatto", 500, 1)); // 3. onj
HatIdCsV *gore = /// miért nem Alkalmazott* ?
new HatIdCsV("Mr. Tejfel", 600, 2, 1000); // 4. obj
#if ELKESZULT == 0
/// ha nincs virtualis öröklés
munkahely.felvesz(dynamic_cast<CsopVez*>(gore)); // 5. obj.
HatIdCsVezH *saf = new HatIdCsVezH("Safranek", 700, 1000, *gore);
munkahely.felvesz(dynamic_cast<CsopVez*>(saf)); /// miért kell a cast ?
#else
/// ha van virtualis öröklés
munkahely.felvesz(gore); /// miért nem kell már a cast ?
munkahely.felvesz(new HatIdCsVezH("Safranek", 700, 1000, *gore)); // 5. obj.
#endif
cout << endl;
munkahely.kiir();
#if ELKESZULT >= 2
void perzTest();
perzTest();
#endif
} catch (std::exception& e) {
std::cout << "*** Kivetel: *** " << e.what() << std::endl;
}
// Itt a vége
std::cout << "ELKESZULT = " << ELKESZULT << std::endl;
if (ELKESZULT < 4 && !gtest_lite::test.fail())
FAIL() << "\nLegalabb az elso negy feladatot oldja meg!" << std::endl;
if (ELKESZULT >= 6 && !gtest_lite::test.fail())
std::cout << "Szuper! Mind kesz" << std::endl;
GTEND(std::cerr); // Csak C(J)PORTA működéséhez kell
return 0;
}
#ifndef TEST_LEVEL_H
#define TEST_LEVEL_H
#define ELKESZULT 0
#endif // TEST_LEVEL_H
/**
* \file iroda.h
* Iroda osztály deklarációja
* Az egyszerűség kedvéért minden tagfüggvényt inline valósítottunk meg.
*
*/
#ifndef IRODA_H
#define IRODA_H
#include <vector>
#include "memtrace.h"
#include "alkalmazott.h"
/**
* Iroda osztály.
* Standard tárolót használ
*/
class Iroda {
/// saját típus, hogy könnyen le tudjuk cserélni a tárolót
/// a tároló POINTERT tárol (heterogén gyűjtemény)
typedef std::vector<Alkalmazott*> tarolo_tipus;
tarolo_tipus t;
Iroda(const Iroda&); /// így nem elérhető
Iroda& operator=(const Iroda&); /// így nem elérhető
public:
/// Mivel van copy, ezért kell a paraméter nélküli.
Iroda() {}
/// Alkalmazottat vesz fel
/// @param p - alkalmazott pointere
void felvesz(Alkalmazott *p) {
t.insert(t.end(), p); /// insert metódusa minden standard tárolónak van
}
/// Meghívjuk a tárolóban levõ összes obj. kiír metódusát
void kiir(std::ostream& os = std::cout) {
/// iterátora minden standard tárolónak van
for (tarolo_tipus::iterator i = t.begin(); i != t.end(); ++i)
(*i)->kiir(os); /// figyelje meg az indirekciót!
}
/// Megszüntetjük a tárolt objektumokat
~Iroda() {
for (tarolo_tipus::iterator i = t.begin(); i != t.end(); ++i)
delete *i; /// figyelje meg az indirekciót!
}
};
#endif // IRODA_H
/**
* \file irodistak.h
* Minden származtatott osztály deklarációját ebbe a fájlba tettük.
* Az egyszerűség kedvéért minden tagfüggvényt inline valósítottunk meg.
*
*/
#ifndef IRODISTAK_H
#define IRODISTAK_H
#include <iostream>
#include <string>
#include "alkalmazott.h"
typedef int csop_t; // csoport típusa
/**
* Csoportvezető
*/
class CsopVez : public Alkalmazott {
csop_t csoport; // csoport azon.
public:
CsopVez(const std::string& n, double f, csop_t cs)
: Alkalmazott(n, f), // alaposztály inicializálása
csoport(cs) // csoport inicializálás
{}
csop_t getCs() const { // csoport lekérdezése
return csoport;
}
void setCs(csop_t cs) {
csoport = cs;
}
void kiir(std::ostream& os = std::cout) const {
os << "CsopVez: ";
Alkalmazott::kiir(os);
}
};
/**
* Határozott idejű alkalmazott
*/
class HatIdeju : public Alkalmazott {
protected:
time_t ido; // szerződése lejár ekkor
public:
HatIdeju(const std::string& n, double f, time_t t)
: Alkalmazott(n, f), // alaposztály inicializálása
ido(t) // ido inicializálás
{}
time_t getIdo() const {
return ido;
}
void setIdo(time_t t) {
ido = t;
}
void kiir(std::ostream& os = std::cout) const {
std::cout << "HatIdeju: ";
Alkalmazott::kiir(os);
}
};
/**
* Határozott idejű csoportvezető
*/
class HatIdCsV :public CsopVez, public HatIdeju {
public:
HatIdCsV(const std::string& n, double f, csop_t cs, time_t t)
: // virtuális alaposztálynál ide kell majd valami
CsopVez(n, f*2, cs), // szándékosan más fizetést kap,
HatIdeju(n, f*10, t) // hogy látható legyen az adatduplikáció
{}
void kiir(std::ostream& os = std::cout) const {
std::cout << "HatIdCsv:" << std::endl << " ";
CsopVez::kiir(os);
std::cout << " ";
HatIdeju::kiir(os);
}
};
/**
* Határozott idejű csoportvezető helyettes
*/
class HatIdCsVezH :public HatIdCsV {
public:
HatIdCsVezH(const std::string& n, double f, time_t t, CsopVez& kit)
: // virtuális alaposztálynál ide kell majd valami
HatIdCsV(n, f, kit.getCs(), t)// alaposztály
{}
void kiir(std::ostream& os = std::cout) const {
std::cout << "HatIdCsVezH: ";
HatIdCsV::kiir(os);
}
};
#endif // IRODISTAK_H
/*********************************
Memoriaszivargas-detektor
Keszitette: Peregi Tamas, BME IIT, 2011
petamas@iit.bme.hu
Kanari: Szeberenyi Imre, 2013.,
VS 2012: Szeberényi Imre, 2015.,
mem_dump: 2016.
inclue-ok: 2017., 2018. 2019.
*********************************/
#ifndef MEMTRACE_H
#define MEMTRACE_H
#if defined(MEMTRACE)
/*ha definiálva van, akkor a hibakat ebbe a fajlba írja, egyébkent stderr-re*/
/*#define MEMTRACE_ERRFILE MEMTRACE.ERR*/
/*ha definialva van, akkor futas kozben lancolt listat epit. Javasolt a hasznalata*/
#define MEMTRACE_TO_MEMORY
/*ha definialva van, akkor futas kozben fajlba irja a foglalasokat*/
/*ekkor nincs ellenorzes, csak naplozas*/
/*#define MEMTRACE_TO_FILE*/
/*ha definialva van, akkor a megallaskor automatikus riport keszul */
#define MEMTRACE_AUTO
/*ha definialva van, akkor malloc()/calloc()/realloc()/free() kovetve lesz*/
#define MEMTRACE_C
#ifdef MEMTRACE_C
/*ha definialva van, akkor free(NULL) nem okoz hibat*/
#define ALLOW_FREE_NULL
#endif
#ifdef __cplusplus
/*ha definialva van, akkor new/delete/new[]/delete[] kovetve lesz*/
#define MEMTRACE_CPP
#endif
#if defined(__cplusplus) && defined(MEMTRACE_TO_MEMORY)
/*ha definialva van, akkor atexit helyett objektumot hasznal*/
/*ajanlott bekapcsolni*/
#define USE_ATEXIT_OBJECT
#endif
/******************************************/
/* INNEN NE MODOSITSD */
/******************************************/
#ifdef NO_MEMTRACE_TO_FILE
#undef MEMTRACE_TO_FILE
#endif
#ifdef NO_MEMTRACE_TO_MEMORY
#undef MEMTRACE_TO_MEMORY
#endif
#ifndef MEMTRACE_AUTO
#undef USE_ATEXIT_OBJECT
#endif
#ifdef __cplusplus
#define START_NAMESPACE namespace memtrace {
#define END_NAMESPACE } /*namespace*/
#define TRACEC(func) memtrace::func
#include <new>
#else
#define START_NAMESPACE
#define END_NAMESPACE
#define TRACEC(func) func
#endif
// THROW deklaráció változatai
#if defined(_MSC_VER)
// VS rosszul kezeli az __cplusplus makrot
#if _MSC_VER < 1900
// * nem biztos, hogy jó így *
#define THROW_BADALLOC
#define THROW_NOTHING
#else
// C++11 vagy újabb
#define THROW_BADALLOC noexcept(false)
#define THROW_NOTHING noexcept
#endif
#else
#if __cplusplus < 201103L
// C++2003 vagy régebbi
#define THROW_BADALLOC throw (std::bad_alloc)
#define THROW_NOTHING throw ()
#else
// C++11 vagy újabb
#define THROW_BADALLOC noexcept(false)
#define THROW_NOTHING noexcept
#endif
#endif
START_NAMESPACE
int allocated_blocks();
END_NAMESPACE
#if defined(MEMTRACE_TO_MEMORY)
START_NAMESPACE
int mem_check(void);
END_NAMESPACE
#endif
#if defined(MEMTRACE_TO_MEMORY) && defined(USE_ATEXIT_OBJECT)
#include <cstdio>
START_NAMESPACE
class atexit_class {
private:
static int counter;
static int err;
public:
atexit_class() {
#if defined(CPORTA) && !defined(CPORTA_NOSETBUF)
if (counter == 0) {
setbuf(stdout, 0);
setbuf(stderr, 0);
}
#endif
counter++;
}
int check() {
if(--counter == 0)
err = mem_check();
return err;
}
~atexit_class() {
check();
}
};
static atexit_class atexit_obj;
END_NAMESPACE
#endif/*MEMTRACE_TO_MEMORY && USE_ATEXIT_OBJECT*/
/*Innentol csak a "normal" include eseten kell, kulonben osszezavarja a mukodest*/
#ifndef FROM_MEMTRACE_CPP
#include <stdlib.h>
#ifdef __cplusplus
#include <iostream>
/* ide gyűjtjük a nemtrace-vel összeakadó headereket, hogy előbb legyenek */
#include <fstream> // VS 2013 headerjében van deleted definició
#include <sstream>
#include <vector>
#include <list>
#include <map>
#include <algorithm>
#include <functional>
#endif
#ifdef MEMTRACE_CPP
namespace std {
typedef void (*new_handler)();
}
#endif
#ifdef MEMTRACE_C
START_NAMESPACE
#undef malloc
#define malloc(size) TRACEC(traced_malloc)(size,#size,__LINE__,__FILE__)
void * traced_malloc(size_t size, const char *size_txt, int line, const char * file);
#undef calloc
#define calloc(count,size) TRACEC(traced_calloc)(count, size, #count","#size,__LINE__,__FILE__)
void * traced_calloc(size_t count, size_t size, const char *size_txt, int line, const char * file);
#undef free
#define free(p) TRACEC(traced_free)(p, #p,__LINE__,__FILE__)
void traced_free(void * p, const char *size_txt, int line, const char * file);
#undef realloc
#define realloc(old,size) TRACEC(traced_realloc)(old,size,#size,__LINE__,__FILE__)
void * traced_realloc(void * old, size_t size, const char *size_txt, int line, const char * file);
void mem_dump(void const *mem, size_t size, FILE* fp);
END_NAMESPACE
#endif/*MEMTRACE_C*/
#ifdef MEMTRACE_CPP
START_NAMESPACE
#undef set_new_handler
#define set_new_handler(f) TRACEC(_set_new_handler)(f)
void _set_new_handler(std::new_handler h);
void set_delete_call(int line, const char * file);
END_NAMESPACE
void * operator new(size_t size, int line, const char * file) THROW_BADALLOC;
void * operator new[](size_t size, int line, const char * file) THROW_BADALLOC;
void * operator new(size_t size) THROW_BADALLOC;
void * operator new[](size_t size) THROW_BADALLOC;
void operator delete(void * p) THROW_NOTHING;
void operator delete[](void * p) THROW_NOTHING;
/* Visual C++ 2012 miatt kell, mert háklis, hogy nincs megfelelő delete, bár senki sem használja */
void operator delete(void *p, int, const char *) THROW_NOTHING;
void operator delete[](void *p, int, const char *) THROW_NOTHING;
#define new new(__LINE__, __FILE__)
#define delete memtrace::set_delete_call(__LINE__, __FILE__),delete
#ifdef CPORTA
#define system(...) // system(__VA_ARGS__)
#endif
#endif /*MEMTRACE_CPP*/
#endif /*FROM_MEMTRACE_CPP*/
#endif /*MEMCHECK*/
#endif /*MEMTRACE_H*/
/**
* \file palkalmazott.h
* Perzisztens viselkedésre képes Alkalmazott alaposztály deklarációja
* Az egyszerűség kedvéért minden tagfüggvényt inline valósítottunk meg.
*
*/
#ifndef PALKALMAZOTT_H
#define PALKALMAZOTT_H
#include <string>
#include <stdexcept>
#include "alkalmazott.h"
#include "serializable.h"
/*
* Perzisztens Alkalmazott
*/
struct PAlkalmazott : public Alkalmazott, public Serializable {
PAlkalmazott(const std::string& n, double fiz) : Alkalmazott(n, fiz) {}
PAlkalmazott(const Alkalmazott& alk) :Alkalmazott(alk) {}
void write(std::ostream& os) const {
os << "PAlkalmazott" << std::endl;
os << getNev() << std::endl;
os << getFiz() << std::endl;
}
void read(std:: istream& is) {
std::string tmp;
(is >> tmp).ignore(1);
if (tmp != "PAlkalmazott") throw std::out_of_range("PAlkalmazott_R: "+tmp);
std::string n;
getline(is, n);
setNev(n);
double f;
(is >> f).ignore(1);
setFiz(f);
}
};
#endif // PALKALMAZOTT_H
/**
* \file perziszt.cpp
*/
#include "elkeszult.h"
/// Ellenőrizzük, hogy az elkeszult.h-ban definiálta-e az ELKESZULT makrót
#ifndef ELKESZULT
#define ELKESZULT 0 /// ha mégse definiálta
#endif
#if ELKESZULT < 0 /// ha hibásan definiálta
#undef ELKESZULT
#define ELKESZULT 0
#endif
/// ------- Ellenőrző rész vége ----------
#include <iostream>
#include <sstream>
#include "palkalmazott.h"
#if ELKESZULT >= 3
# include "pirodistak.h"
#endif
#include "gtest_lite.h"
void perzTest(){
TEST(perzist, Alkalmazott) {
std::stringstream ss;
Alkalmazott ld("Lusta Dick", 100);
PAlkalmazott(ld).write(ss);
PAlkalmazott rsLd("", 0);
rsLd.read(ss);
EXPECT_EQ(ld.getNev(), rsLd.getNev());
EXPECT_EQ(ld.getFiz(), rsLd.getFiz());
END }
#if ELKESZULT >= 3
TEST(perzist, CsopVez) {
std::stringstream ss;
CsopVez gt("Mr. Gatto", 100, 5);
PCsopVez(gt).write(ss);
PCsopVez rsGt("", 0, 0);
rsGt.read(ss);
EXPECT_EQ(gt.getNev(), rsGt.getNev());
EXPECT_EQ(gt.getFiz(), rsGt.getFiz());
EXPECT_EQ(gt.getCs(), rsGt.getCs());
END }
#endif
#if ELKESZULT >= 4
TEST(perzist, HatIdeju) {
std::stringstream ss;
HatIdeju gr("Grabovszki", 100, 5000);
PHatIdeju(gr).write(ss);
PHatIdeju rsGr("", 0, 0);
rsGr.read(ss);
EXPECT_EQ(gr.getNev(), rsGr.getNev());
EXPECT_EQ(gr.getFiz(), rsGr.getFiz());
EXPECT_EQ(gr.getIdo(), rsGr.getIdo());
END }
#endif
#if ELKESZULT >= 5
TEST(perzist, HatIdCsV) {
std::stringstream ss;
HatIdCsV tf("Mr. Tejfel", 100, 5555, 3);
PHatIdCsV(tf).write(ss);
PHatIdCsV rstf("", 0, 0, 0);
rstf.read(ss);
EXPECT_EQ(tf.getNev(), rstf.getNev());
EXPECT_EQ(tf.getFiz(), rstf.getFiz());
EXPECT_EQ(tf.getCs(), rstf.getCs());
EXPECT_EQ(tf.getIdo(), rstf.getIdo());
END }
#endif
#if ELKESZULT >= 6
TEST(perzist, HatIdCsVezH) {
std::stringstream ss;
HatIdCsV tf("Mr. Tejfel", 100, 5555, 3);
HatIdCsVezH safi("Safranek", 100, 55, tf);
PHatIdCsVezH(safi).write(ss);
PHatIdCsVezH rsafi("", 0, 0, tf);
rsafi.read(ss);
EXPECT_EQ(safi.getNev(), rsafi.getNev());
EXPECT_EQ(safi.getFiz(), rsafi.getFiz());
EXPECT_EQ(safi.getCs(), rsafi.getCs());
EXPECT_EQ(safi.getIdo(), rsafi.getIdo());
END }
#endif
}
/**
* \file pirodistak.h
* Minden származtatott irodista osztály perzisztens változatának deklarációját ebbe a fájlba tegye!
* Az egyszerűség kedvéért minden tagfüggvényt inline valósítson meg!
*
*/
#ifndef PIRODISTAK_H
#define PIRODISTAK_H
#include <stdexcept>
#include "palkalmazott.h"
#include "irodistak.h"
#error " itt készitse el a PCsopVez, PHatIdeju, PHatIdCsV és PHatIdCsVezH, osztályokat!"
/**
* Perzisztens csoportvezető
*/
/**
* Perzisztens Határozott idejű alkalmazott
*/
/**
* Perzisztens Határozott idejű csoportvezető
*/
/**
* Perzisztens Határozott idejű csoportvezető helyettes
*/
#endif // IRODISTAK_H
#ifndef SERIALIZABLE_H
#define SERIALIZABLE_H
#include <iostream>
struct Serializable {
virtual void write(std::ostream&) const = 0;
virtual void read(std::istream&) = 0;
virtual ~Serializable() {}
};
#endif // SERIALIZABLE_HPP
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment