Polyset

Código comentado línea a línea y paso a paso:

Entregas: searchable_array_bag.*, searchable_tree_bag.*, set.*. Flags: c++ -Wall -Wextra -Werror -std=c++98

Qué pide (en palabras normales)

Subject (enunciado original)
Assigment name: Polyset
Expected File: searchable_array_bag.cpp, searchable_array_bag.hpp,
searchable_tree_bg.cpp, searchable_tree_bag.hpp, set.cpp, set.hpp

You will find in this directory some classes:
- bag: an abstract class representing a bag
- searchable_bag: an abstract class representing a bag with the ability to
	search in it.
- array_bag: an implementation of a bag with an array an underlying data
	structure.
- tree_bag: an implementation of a bag with a binary search tree as underlying
	data structure.

If you don't know what is a set or a bag (shame!) you can read the attached
file shame.en.txt

First Part:
Since a bag without a searching function isn't very useful, implement two
classes searchable_array_bag and searchable_tree_bag, that will inherit from
array_bag and tree_bag and implement the searchable bag abstract class.

Second Part:
Implement the class set that will wrap a searchable_bag and turn it into a set.
You will find in this dir a main that must compile with your code.
All classes should be under orthodox canonical form. Don't forget the const.

[MAIN]
#include "searchable_bag.hpp"
#include "searchable_tree_bag.hpp"
#include "searchable_array_bag.hpp"
#include "set.hpp"

#include <iostream>
#include <stdlib.h>

int main(int argc, char **argv)
{
	if (argc == 1)
		return 1;
	searchable_bag *t = new searchable_tree_bag;
	searchable_bag *a = new searchable_array_bag;

	for (int i = 1; i < argc; i++) {
		t->insert(atoi(argv[i]));
		a->insert(atoi(argv[i]));
	}
	t->print();
	a->print();

	for (int i = 1; i < argc; i++)
	{
		std::cout << t->has(atoi(argv[i])) << std::endl;
		std::cout << a->has(atoi(argv[i])) << std::endl;
		std::cout << t->has(atoi(argv[i]) - 1) << std::endl;
		std::cout << a->has(atoi(argv[i]) - 1) << std::endl;
	}

	t->clear();
	a->clear();

	const searchable_array_bag tmp(static_cast<searchable_array_bag &>(*a));
	tmp.print();
	tmp.has(1);

	set sa(*a);
	set st(*t);
  int intArr[] = {1, 2, 3, 4};
	for (int i = 1; i < argc; i++)
	{
		st.insert(atoi(argv[i]));
		sa.insert(atoi(argv[i]));

		sa.has(atoi(argv[i]));
		sa.print();
		sa.get_bag().print();
		st.print();
		sa.clear();
		sa.insert(intArr, sizeof(intArr) / sizeof(int));
		std::cout << std::endl;
	}
  
  delete a;
  delete t;
	return (0);
}

Mapa

            bag  (insert, insert[], print, clear)
          /      \         virtual public → diamante
   array_bag    searchable_bag  (+ bool has(int) const = 0)
   tree_bag          |
        \          /
   searchable_array_bag / searchable_tree_bag   → solo añaden has()

   set  ──contiene──▶  searchable_bag &bag        → NO hereda, delega

3 piezas

1. this = "yo"

this = el objeto que ejecuta la función ("yo"). *this = yo mismo.

2. const al final = "solo miro"

class Contador
{
	int n;
public:
	void sumar()     { n++; }       // me cambia → SIN const
	int  ver() const { return n; }  // solo mira → CON const
};

Pregunta única: ¿cambia algo de mi objeto? No → const · Sí → sin const.

Por qué importa: un objeto const solo puede usar funciones const. El main hace const searchable_array_bag tmp(...); tmp.has(1); → has tiene que ser const.

3. return *this = "me devuelvo a mí"

searchable_array_bag&	searchable_array_bag::operator=(const searchable_array_bag& other)
{
	if (this != &other)
		array_bag::operator=(other);   // copia el padre
	return *this;                      // me devuelvo a mí
}

En polyset solo sale en operator=. Truco: si ves return *this;, delante va Clase &. Siempre juntos.

Polyset

Con searchable_array_bag. En tree: cambia array → tree.

Función¿Cambia algo?Firma
constructor-searchable_array_bag();
copia-searchable_array_bag(const searchable_array_bag &src);
destructor-~searchable_array_bag();
=sí → sin const · return *thissearchable_array_bag &operator=(const searchable_array_bag &src);
hasno → constbool has(int value) const;
set
constructor-set(searchable_bag &b);
insertsí → sin constvoid insert(int value);
clearsí → sin constvoid clear();
printno → constvoid print() const;
hasno → constbool has(int value) const;
get_bagno → constconst searchable_bag &get_bag() const;

get_bag lleva dos const: delante = "lo que te doy no lo toques" · detrás = "yo no me toco".

Cuerpos

copia        : array_bag(other) {}
=            if (this != &other) array_bag::operator=(other); return *this;
has (array)  bucle i < size → data[i] == value
set(b)       : bag(b) {}                  (referencia → obligatorio aquí)
set::insert  if (!bag.has(v)) bag.insert(v);
set()  copia  =     private y sin cuerpo  (C++98 no tiene = delete)
resto de set print / clear / has / get_bag → se lo pasa a bag

Optim: declaraciones en el .hpp y cuerpos en el .cpp. En el .cpp lo que sale va delante del dueño: searchable_array_bag &searchable_array_bag::operator=(...)

Cristi: todo escrito dentro del .hpp (cuerpos inline) y los .cpp solo incluyen su .hpp. Menos que escribir, mismo resultado.

has() del árbol

node *cur = tree;
while (cur)
    ==  → true
    <   → cur->l
    >   → cur->r
NULL → false

Checklist