Commit 5d874eaa by Szeberényi Imre

v0

parents
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="6" />
<Project>
<Option title="ClonableHetero" />
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="Debug">
<Option output="bin/Debug/Cpp Hetero" 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/Cpp Hetero" 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" />
<Add option="-Wall" />
<Add option="-Werror" />
</Compiler>
<Unit filename="bacterium.h" />
<Unit filename="clonable.h" />
<Unit filename="clonable_bacterium.h" />
<Unit filename="clonable_hetero_store.hpp" />
<Unit filename="clonable_hetero_test.cpp" />
<Unit filename="clonable_testclass.h" />
<Unit filename="gtest_lite.h" />
<Unit filename="memtrace.cpp" />
<Unit filename="memtrace.h" />
<Unit filename="testclass.h" />
<Extensions>
<code_completion />
<envvars />
<debugger />
</Extensions>
</Project>
</CodeBlocks_project_file>
#
# Makefile pelda a clonable hetero feladat megoldasanak forditasara
# gnumake valtozat
# Linuxokon es ural2-n is elerheto
#
PROG = clonable_hetero_test # a program neve (ezt allitjuk elo)
PROG_O = clonable_hetero_test.o # program object fajljai
PROG_H = clonable_hetero_store.hpp bacterium.h gtest_lite.h testclass.h clonable_bacterium.h clonable_testclass.h # program header fajljai
PROG_L = # program libjei
MTRACE_O = memtrace.o # memtrace object fajl
MTRACE_H = memtrace.h # memtrace es memcheck header fajlja
CXX = g++ # a C fordito neve
#CXX = clang++ # clang-ot (llvm) is erdemes kiprobalni
CXXFLAGS = -pedantic -Wall -Werror -std=gnu++98 # kapcsolok: legyen bobeszedu es pedans
CXXFLAGS += -ggdb -DMEMTRACE -DBACI_IS_VAN # es legyen debug info is
LDFLAGS = -ggdb # debug a linkelesnel
# osszes object, osszes header osszes lib
OBJS = $(PROG_O) $(MTRACE_O)
HEADS = $(PROG_H) $(MTRACE_H)
LIBS = $(PROG_L)
# alapertelmezett cel: program
.PHONY: all
all: $(PROG)
$(PROG): $(OBJS)
$(CXX) $(LDFLAGS) $(OBJS) -o $@ $(LIBS)
# feltetelezzuk, hogy az osszes obj fugg az osszes headertol
$(OBJS): $(HEADS)
# takaritas igeny szerint
.PHONY: clean
clean:
rm -f $(OBJS) $(PROG)
/**
* \file: bacterium.h
*
* Bacterium alaposztály és leszármazottjai
*/
#ifndef BACTERIUM_H
#define BACTERIUM_H
#include <string>
/// Bacterium osztály.
class Bacterium {
std::string name;
public:
/// @param n - baktérium neve
Bacterium(const char *n = "") : name(n) {}
/// show
/// @param os - adatfolyam amire kiírja a nevét
virtual void show(std::ostream& os) const {
os << "Bakterium " << name;
};
virtual ~Bacterium() {}
};
/// Salmonella osztály.
/// Bacterium virtuális alaposztályból származik
/// a többszörös öröklési úton való elérésből adódó problémák kiküszöbölése miatt.
class Salmonella : virtual public Bacterium {
std::string species; // faj neve
public:
/// @param n - salmonella fajtája
Salmonella(const char *sp) :Bacterium("Salmonella"), species(sp) {}
/// show
/// @param os - adatfolyam amire kiírja a nevét és fajtáját
void show(std::ostream& os) const {
Bacterium::show(os);
os << " Fajta: " << species;
}
};
/// Streptococcus osztály.
/// Bacterium virtuális alaposztályból származik
/// a többszörös öröklési úton való elérésből adódó problémák kiküszöbölése miatt.
class Streptococcus : virtual public Bacterium {
char group; // csoport neve
public:
/// @param n - Streptococus baci csoportja
Streptococcus(char grp) :Bacterium("Streptococcus"), group(grp) {}
/// show
/// @param os - adatfolyam amire kiírja a nevét és csoportját
void show(std::ostream& os) const {
Bacterium::show(os);
os << " Csoport: " << group;
}
};
/// Funktor a kiíráshoz
/// Konstruktor paraméterben megadott adatfolyamra ír
class BacteriumShow {
std::ostream& os;
public:
BacteriumShow(std::ostream& os = std::cout) :os(os) {}
void operator()(Bacterium *p) {
p->show(os);
os << std::endl;
}
};
#endif // BACTERIUM_H
/**
* \file: clonable.h
*
* Clonable absztrakt osztály
*/
#ifndef CLONABLE_H
#define CLONABLE_H
/// Clonable absztrakt osztály.
struct Clonable {
/// Előállít egy önmagával azonos példányt
virtual Clonable* clone() const = 0;
virtual ~Clonable() {};
};
#endif // CLONABLE_H
/**
* \file: clonable_bacterium.h
*
*/
#ifndef CLONABLE_BACTERIUM_H
#define CLONABLE_BACTERIUM_H
#include "bacterium.h"
#include "clonable.h"
#error "itt készítse el Baktérium osztályok klonozható változatát"
/**
* A ClonableBacterium, ClonableSalmonella, ClonableStreptococcus
* osztályoknak kompatibilisnek kell lennie a Bacterium és Clonable osztályokkal.
* A funkciókat tekintve meg kell egyezni a Bacterium, Salmonella, Streptococcus
* osztályok funkcióival.
*/
#endif // CLONABLE_BACTERIUM_H
/**
* \file: clonable_hetero_store.hpp
*
*/
#ifndef CLONABLE_HETERO_STORE_HPP
#define CLONABLE_HETERO_STORE_HPP
#error "itt készítse el a ClonableHeteroStore sablont"
#endif // CLONABLE_HETERO_STORE_HPP
/**
* \file: clonable_testclass.h
*
*/
#ifndef CLONABLE_TESTCLASS_H
#define CLONABLE_TESTCLASS_H
#include "testclass.h"
#include "clonable.h"
/// ClonableTestClass osztály.
/// TestClass-ból hozza a funkcionalitást,
/// a Clonable-ből pedig a klónozhatóságot.
struct ClonableTestClass : virtual TestClass, Clonable {
ClonableTestClass *clone() const { return new ClonableTestClass(*this); }
};
/// ClonableTestClass1 osztály.
/// TestClass1-ből hozza a funkcionalitást,
/// a ClonableTestClass-ból pedig a klónozhatóságot, de ennek és a TestClass1-nek is
/// alaposztálya a TestClass, ami virtuális alap mindkettőben.
struct ClonableTestClass1 : TestClass1, ClonableTestClass {
ClonableTestClass1(int a = 0) :
// az öröklési a lánc végén meg kell hívni a virt. alaposztály konstrukorát
TestClass(), // ez lenne a default, de kiírjuk, hogy látszódjon
TestClass1(a) { }
ClonableTestClass1 *clone() const { return new ClonableTestClass1(*this); }
};
/// ClonableTestClass2 osztály.
/// TestClass2-ből hozza a funkcionalitást,
/// a ClonableTestClass-ból pedig a klónozhatóságot, de ennek és a TestClass2-nek is
/// alaposztálya a TestClass, ami virtuális alap mindkettőben.
struct ClonableTestClass2 : TestClass2, ClonableTestClass {
ClonableTestClass2(std::string s = "") :
// az öröklési a lánc végén meg kell hívni a virt. alaposztály konstrukorát
TestClass(), // ez lenne a default, de kiírjuk, hogy látszódjon
TestClass2(s) {}
ClonableTestClass2 *clone() const { return new ClonableTestClass2(*this); }
};
#endif // CLONABLE_TESTCLASS_H
**Készítsen** heterogén kollekciók tárolásához sablon osztályt (**ClonableHeteroStore**),
ami egy belső *sorozattároló* segítségével tárolja a heterogén gyűjteményhez tartozó objektumok pointereit!
Sablonparaméterként vegye át a heterogén kollekció alaposztályát, a tároláshoz használt osztályt, valamint egy kivétel osztályt, amit hiba esetén eldob (ld. később)! Amennyiben ez nincs megadva, akkor az *std::out_of_range* kivételt dobja!
Amennyiben a tároló osztályt sem adják meg, akkor azt az *std::vector* sablonból hozza létre!
Az alábbi kódrészlet a sablon példányosítására mutat néhány példát:
ClonableHeteroStore<Ember> t1;
ClonableHeteroStore<Ember>, std::deque<Ember*> t2;
ClonableHeteroStore<Valami, std::list<Valami*>, MyClass> t3;
Ahol:
- t1 - *Ember\** típusú pointereket tárol *std::vector* sablon segítségével. Hiba esetén *std::out_of_range* kivételt dob.
- t2 - *Ember\** típusú pointereket tárol *std::deque* sablon segítségével. Hiba esetén *std::out_of_range* kivételt dob.
- t3 - *Valami\** típusú pointereket tárol *std::list* sablon segítségével. Hiba esetén *MyClass* kivételt dob.
A Sablonparaméterként megadható sorozattárolónak az alábbi minimumkövetelményeknek kell megfelelnie:
- A paraméterként átadott tárolótól elvárjuk, hogy legyen:
- létrehozható, megszüntethető, másolható, értékadható
- A paraméterként átadott tárolótól elvárjuk, hogy megvalósítja az alábbi metódusokat illetve típusokat:
- *value\_type* - a tárolt adat típusa.
- *iterator* - iterátor.
- *const\_iterator* - konstans iterátor.
- *begin()*, *end()* - visszaad egy iterátort, ami az első adatra, illetve az utolsó adat után mutat.
- *size()* - visszaadja a tárolt elemek számát.
- *push\_back()* - betesz egy új adatot a tárolóba - pontosabban az adat egy másolatát - a tárolt adatok után. Amennyiben helyhiány miatt ez nem sikerül, *std::bad_alloc* kivételt dob.
- *clear()* - törli a tárolót, azaz eldobja a tárolt adatokat, a tárolt darabszámot 0-ra állítja.
A fentieket felhasználva **valósítsa** meg (tegye elérhetővé) a *ClonableHeteroStore* osztály az alábbi publikus metódusokat illetve típusokat:
- **const_iterator** - konstans iterátor.
- **begin()** - visszaad egy iterátort (*const\_iterator*) a belső tároló első elemére.
- **end()** - visszaad egy iterátort (*const\_iterator*), ami a belső tárolóban tárolt utolsó elem után mutat.
- **size_t size()** - megadja a tárolt pointerek számát
- **void add(p)** - beteszi a tárolóba a paraméterként kapott pointert.
Amennyiben a tárolóba már nem tudja betenni a pointert, dobjon kivételt!
- **void clear()** - törli (felszabadítja) a tárolóban tárolt objektumokat.
Legyenek a **ClonableHeteroStore** osztályból létrehozott objektumok másolhatók és szerepelhessenek értékadás bal oldalán is!
Támogassa a többszörös értékadást! **Tételezze fel**, hogy a tárolóban tárolt heterogén gyűjtemény osztályainak van **clone()** metódusa, ami egy teljes másolatot (deep copy) készít az adott objektumról.
**Feladatok:**
1. Töltse le az előkészített projektet a tárolóból!
[https://git.ik.bme.hu/Prog2/ell_feladat/ClonableHetero](https://git.ik.bme.hu/Prog2/ell_feladat/ClonableHetero.git)
2. Készítse el a **ClonableHeteroStore** osztályt a *clonable_hetero_store.hpp* állományban!
3. Tesztelje a megadott tesztprogrammal az új osztályt!
4. Elemezze a **ClonableTestClass**, a **ClonableTestClass1**, valamint a **ClonableTestClass2** osztályok megvalósítását a *clonable_testclass.h* állományban! A megvalósítás többszörös öröklést és virtuális alaposztályt használ. Értse meg, hogy miért van erre szükség!
5. A fentiek alapján hozzon létre klónozható baktériumokat, melyek kompatibilisek a **Bacterium**, valamint **Clonable** osztályokkal! Az osztályokat a *clonable_bacterium.h* fájlban implementálja!
6. Definiálja a **BACI\_IS\_VAN** makrót, fordítson és ismét teszteljen!
4. Amennyiben a tesztek jól futnak, töltse fel a *JPorta* feladatbeadó rendszerbe a **clonable\_bacterium.h** és **clonable\_hetero\_store.hpp** fájlokat!
**Megjegyzések:**
- Dinamikusan keletkező objektumok esetében fontos kérdés, hogy ki hozza létre és ki szünteti meg az objektumot, azaz mikor ki felel az objektumért. Ügyeljen arra, hogy a tárolónak átadott **"objektumért" a tároló felel**. Még akkor is, ha nem tudta elhelyezni azt a tárolóban.
- Azzal, hogy a tárolt elemek iterátorral is elérhetők, nincs szükség külön bejáró (traverse) tagfüggvényre. A tároló az iterátor segítségével egyszerűen bejárható.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
/*********************************
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: bacterium.h
*
* TestClass alaposztály és leszármazottjai
*/
#ifndef TESTCLASS_H
#define TESTCLASS_H
#include <string>
/// TestClass osztály.
struct TestClass {
virtual void print(std::ostream&) const {} ;
virtual ~TestClass() {}
};
/// TestClass1 osztály.
/// TestClass virtuális alaposztályból származik
/// a többszörös öröklési úton való elérésből adódó problémák kiküszöbölése miatt.
class TestClass1 : virtual public TestClass {
int adat;
public:
TestClass1(int a = 0) : adat(a) { }
void print(std::ostream& os) const {
os << adat << ';';
}
};
/// TestClass2 osztály.
/// TestClass virtuális alaposztályból származik
/// a többszörös öröklési úton való elérésből adódó problémák kiküszöbölése miatt.
class TestClass2 : virtual public TestClass {
std::string str;
public:
TestClass2(std::string s = "") : str(s) {}
void print(std::ostream& os) const {
os << str << ';';
}
};
/// Funktor a kiíráshoz
/// Konstruktor paraméterben megadott adatfolyamra ír
class TestClassPrint {
std::ostream& os;
public:
TestClassPrint(std::ostream& os = std::cout) :os(os) {}
void operator()(TestClass *p) {
p->print(os);
}
};
#endif // TESTCLASS_H
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