This is the header of my project (I know it's not ideal to contain all the classes at the same header but this is the requirement of our presubmission tool).
Maybe you can review the header and give some feedback on the construction and design from an "OOP view of point".
Thanks in advance!
Code:
#ifndef FRACTAL_H
#define FRACTAL_H
#include <vector>
#include <string>
#include <iosfwd>
const char WHITESPACE = ' ';
const std::string FRACTALCELL = "#";
const int FIRSTTYPE = 1;
const int SECONDTYPE = 2;
const int FIRSTBASEDIM = 3;
const int SECONDBASEDIM = 2;
const int THIRDBASEDIM = 3;
/**
* @class Fractal
* @brief Abstract class for specific fractals to be depicted
*/
class Fractal
{
public:
/**
* @brief Destructor of Fractal base class - to be able to destroy the sub-objects of the base class
* There are no some buffers/new allocations in this class - so the default one is sufficient
*/
virtual ~Fractal() = default;
protected:
const int m_Dim; // Dimension of the fractal grid
std::vector<std::vector<bool>> m_Pattern; // Grid matrix representation via boolean values
mutable std::vector<std::string> m_Output; // The final fractal grid's lines
/**
* @brief Constructor of base-class sub-objects
* @param dim The dimension of the fractal to be drawn
*/
explicit Fractal(int dim);
/**
* @brief Here we use the OOP concept of Factory Method Pattern
* Using this method, we can create derived-fractal objects without having to specify the exact
* class type of the object that will be created.
* @param smallerDim The dimension of the sub-fractal of another fractal
* Thus, this dimension will always be lower than the superior fractal by 1.
* @return Specific deriving class object - in particular, a sub-fractal .
*/
virtual Fractal *_smallerClone(int smallerDim) const = 0;
/**
* @brief This function is recursively building the grid of our fractal.
* @return Returns the lines of its final representative grid.
*/
std::vector<std::string> toLines() const;
/**
* @brief This is an helper function of toString method - it generates one string that contains at once
* all the lines of the grid received from toLines method
* @return Returns the output-stream received, buffered with the suitable string.
*/
std::ostream &toString(std::ostream &os) const;
/**
* @brief The print function - the requested output stream is buffered with the draw of a fractal
* and is output.
* @param os The chosen output stream
* @param f The fractal to be printed
* @return Reference to the exact output stream, now buffered with the draw of fractal f
*/
friend std::ostream &operator<<(std::ostream &os, const Fractal &f); // The actual print function
};
/**
* @class Deriving class of Fractal
* @brief represents specific kind of fractal to be output
*/
class SierpinskyCarpet: public Fractal
{
public:
/**
* @brief Constructor of a specific fractal
* @param dim The dimension of the fractal
*/
explicit SierpinskyCarpet(int dim);
private:
/**
* @brief Using this method, we can create SierpinskyCarpet fractal objects without having to
* specify the exact class type at run-time.
* @param smallerDim The dimension of the sub-fractal the current fractal
* Thus, this dimension will always be lower than the superior fractal by 1.
* @return Same class object - in particular, a sub-fractal .
*/
SierpinskyCarpet *_smallerClone(int smallerDim) const override;
};
/**
* @class Deriving class of Fractal
* @brief represents specific kind of fractal to be output
*/
class SierpinskyTriangle: public Fractal
{
public:
/**
* @brief Constructor of a specific fractal
* @param dim The dimension of the fractal
*/
explicit SierpinskyTriangle(int dim);
private:
/**
* @brief Using this method, we can create SierpinskyTriangle fractal objects without having to
* specify the exact class type at run-time.
* @param smallerDim The dimension of the sub-fractal the current fractal
* Thus, this dimension will always be lower than the superior fractal by 1.
* @return Same class object - in particular, a sub-fractal .
*/
SierpinskyTriangle *_smallerClone(int smallerDim) const override;
};
/**
* @class Deriving class of Fractal
* @brief represents specific kind of fractal to be output
*/
class Vicsek: public Fractal
{
public:
/**
* @brief Constructor of a specific fractal
* @param dim The dimension of the fractal
*/
explicit Vicsek(int dim);
private:
/**
* @brief Using this method, we can create Vicsek fractal objects without having to
* specify the exact class type at run-time.
* @param smallerDim The dimension of the sub-fractal the current fractal
* Thus, this dimension will always be lower than the superior fractal by 1.
* @return Same class object - in particular, a sub-fractal .
*/
Vicsek *_smallerClone(int smallerDim) const override;
};
/**
* @class Factory class
* @brief Using this class one can generate a specific fractal object
*/
class FractalFactory
{
public:
/**
* @brief Single static method to generate specific fractals
* @param type The type of one of three fractals indicated by 1/2/3
* @param dim The dimension of the wanted fractal
* @return Pointer to object of the specific fractal, held by the base class variable
* Thus, we can perform this way polymorphism as we wish
*/
static Fractal *factoryMethod(int type, int dim);
};
#endif