Class factory to create derived classes c++ - c++

I'm currently learning about class factory patterns with C++. I keep having errors while trying to implement the factory. Suppose I have an abstract class and two derived classes. What I want the factory to do is to create a new object of the base class like so: Ball *sc = new SoccerBall();
I am not sure on how to implement this, I have tried but of no avail. What do I need to fix?
class Ball
{
public:
Ball();
virtual ~Ball();
virtual int getSize() const = 0;
virtual void setBallSize(int s) = 0;
virtual string ballManufacturer() const = 0;
protected:
int ballSize;
}
class Soccerball:public Ball
{
public:
Soccerball();
Soccerball(int size);
~Soccerball();
int getSize() const;
void setBallSize(int s);
string ballManufacturer() const;
}
class Soccerball:public Ball
{
public:
Soccerball();
Soccerball(int size);
~Soccerball();
int getSize() const;
void setBallSize(int s);
string ballManufacturer() const;
}
class Basketball:public Ball
{
public:
Basketball();
Basketball(int size);
~Basketball();
int getSize() const;
void setBallSize(int s);
string ballManufacturer() const;
}
class BallFactory
{
public:
Ball* createBall(string s)
{
if(s == "Soccer")
{
return new Soccerball(5);
}
if(s == "Basket")
{
return new Basketball(6);
}
}
}

This how your code will work, but above when you are posting a question you should provide "Short Self Contained Correct Code" and make easy for people to understand your problem easily.
#include <iostream>
using namespace std;
class Ball
{
public:
Ball()
{
cout<<"Ball ctr"<<endl;
}
virtual ~Ball()
{
}
virtual int getSize() const = 0;
virtual void setBallSize(int s) = 0;
virtual string ballManufacturer() const = 0;
protected:
int ballSize;
};
class Soccerball:public Ball
{
public:
Soccerball()
{
cout<<"create Default Soccer Ball "<<endl;
}
Soccerball(int size)
{
cout<<"create Soccer Ball "<<size<<endl;
}
~Soccerball()
{
}
int getSize() const
{
return ballSize;
}
void setBallSize(int s)
{
ballSize = s;
}
string ballManufacturer() const
{
return "";
}
};
class Basketball:public Ball
{
public:
Basketball()
{
cout<<"create default Baseket Ball "<<endl;
}
Basketball(int size)
{
cout<<"create Baseket Ball "<<size<<endl;
}
~Basketball()
{
}
int getSize() const
{
return ballSize;
}
void setBallSize(int s)
{
ballSize = s;
}
string ballManufacturer() const
{
return "";
}
};
class BallFactory
{
public:
//Factory method
static Ball* createBall(string s)
{
if(s == "Soccer")
{
return new Soccerball(5);
}
if(s == "Basket")
{
return new Basketball(6);
}
}
};
int main()
{
Ball* ptr = BallFactory::createBall("Soccer");
return 0;
}
But you also need to understand how Factory design pattern works and how a namesake virtual constructor is created and why you would use a parameterized factory. Or could you use a template factory.

Related

Convert c++98 code to new c++17 code when using std::vector of pointers

i dont what to manage or less as i can manage raw pointers note in the example i have to delete the object before removeing it from the vector i want to avoid it it here and later
what will be good case to convert this code to using unique_ptr or shared_ptr
class GameState
{
public:
virtual bool onEnter() = 0;
virtual bool onExit() = 0;
virtual std::string getStateID() const = 0;
};
class MenuState : GameState
{
public:
MenuState(){};
virtual ~MenuState(){};
bool onEnter(){};
bool onExit(){};
std::string getStateID() const;
private:
static const std::string s_menuId;
};
class StateMechine
{
public:
void pushState(GameState* pState)
{
m_gameStates.pop_back(pState);
m_gameStates.back()->onEnter();
}
void changeState(GameState* pState)
{
if(!m_gameStates.empty())
{
if(m_gameStates.back()->onExit())
{
delete m_gameStates.back();
m_gameStates.pop_back();
}
}
}
private:
std::vector<GameState*> m_gameStates;
}
int main(int argc ,char** argv)
{
GameState *gs = new MenuState();
StateMechine sm;
sm.pushState(gs);
sm.changeState(gs);
}
The std::vector<GameState*> can be replaced with a std::vector<std::unique_ptr<GameState>>. That way a call to m_gameStates.pop_back() will delete the corresponding object.
class StateMechine
{
public:
void pushState(std::unique_ptr<GameState> pState)
{
m_gameStates.push_back(std::move(pState));
m_gameStates.back()->onEnter();
}
void changeState()
{
if(!m_gameStates.empty())
{
if(m_gameStates.back()->onExit())
{
m_gameStates.pop_back();
}
}
}
private:
std::vector<std::unique_ptr<GameState>> m_gameStates;
};
int main(int argc ,char** argv)
{
StateMechine sm;
sm.pushState(std::make_unique<MenuState>());
sm.changeState();
}

How should i overload += operator in a vector template?

I got a template class Atlas that will store objects of Animal class and derived classes of Animal;
here's the code:
#include <iostream>
#include <assert.h>
#include <list>
using namespace std;
class Animal {
protected:
std::string m_name;
Animal (std::string name): m_name {name} {}
public:
virtual std::string regn() const { return "???"; }
virtual ~Animal(){
cout << "Destructor animal"<<'\n';}
};
class Nevertebrate : public Animal{
public:
virtual std::string regn() const { return "nevertebrate";}
virtual ~Nevertebrate();
};
class Vertebrate: public Animal {
protected:
/* std::string m_name;
Vertebrate (std::string name)
:m_name {name} {} */
Vertebrate (std::string name)
: Animal {name} {}
public:
virtual std::string regn() const { return "vertebrate";}
virtual ~Vertebrate(){
cout<<"Destructor vertebrate"<<'\n';};
};
class bird: public Vertebrate {
public:
bird(std::string name)
: Vertebrate{ name }{}
void set_name (std::string nume){
m_name = nume;}
std::string get_name(){
return m_name;}
virtual std::string regn() const {return "pasare";}
virtual ~bird (){
cout << "destructor bird"<<'\n';}
};
template <class T>
class Atlas
{
private:
int m_length{};
T* m_data{};
public:
void SetLength(int j);
Atlas(int length)
{
assert(length > 0);
m_data = new T[length]{};
m_length = length;
}
Atlas(const Atlas&) = delete;
Atlas& operator=(const Atlas&) = delete;
~Atlas()
{
delete[] m_data;
}
void erase()
{
delete[] m_data;
m_data = nullptr;
m_length = 0;
}
T& operator[](int index)
{
assert(index >= 0 && index < m_length);
return m_data[index];
}
int getLength() const;
};
template <class T>
int Atlas<T>::getLength() const
{
return m_length;
}
template <class T>
void Atlas<T>::SetLength(int j){m_length = j;
}
int main()
{
Atlas<Bird> AtlasBird(10);
Bird b;
AtlasBird.SetLength(11);
AtlasBird[10] = b --- it gets a memoryleak from here.
return 0;
}
I want to overload the += operator so that i can insert a new object into my Atlas, (e.g. AtlasAnimal).
I tried with the SetLength function to increase the length, (e.g. AtlasAnimal.SetLength(11)) but when i try to assign AtlasAnimal[10] an object (e.g. Bird b) it drops a memory leak.
I'm sorry if there was a similar question answered, but i couldn't find anything that helps

Issue with polymorphism with smart pointers and vectors c++

I am currently trying to learn c++ and I am having an issue when trying to create a vector which iterates through several different objects whom all inherit from the same base class with smart pointers.
I parse a file and create the objects and insert them into the vector depending on the character parsed but I keep getting the error:
Error C2664 'std::unique_ptr<Test *,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)': cannot convert argument 1 from 'std::unique_ptr<Test2,std::default_delete<_Ty>>' to 'std::nullptr_t'"
Code is as follows:
class Test {
public:
virtual ~Test(){}
virtual int update() {}
};
class Test2 : public Test {
private:
int a;
public:
Test2() {
}
Test2(int n) {
a = n;
}
int update() override {
return a;
}
};
class Test3 : public Test {
private:
int a;
public:
Test3() {
}
Test3(int n) {
a = n;
}
int update() override {
return a;
}
};
class Test4 : public Test {
private:
int a;
public:
Test4() {
}
Test4(int n) {
a = n;
}
int update() override {
return a;
}
};
class manager {
private:
std::vector<std::unique_ptr<Test*>> vList;
std::ifstream lvlFile;
public:
std::string tmp;
manager() {
}
~manager() {
}
void init(const char *path) {
lvlFile.open(path, 0);
while (lvlFile.eof() != true) {
std::getline(lvlFile, tmp);
for (char& a : tmp) {
switch (a) {
case 'w':
vList.emplace_back(std::make_unique<Test2>(2));
break;
case 'g':
vList.emplace_back(std::make_unique<Test3>(3));
break;
}
}
}
}
void print() {
for (auto& i : vList) {
std::cout << (*i)->update() << std::endl;
}
}
};
manager *m;
int main() {
m = new manager();
m->init("lvl.txt");
_getch();
}
Maybe I have misunderstood something crucial here but I have been looking around and found no real answers so any pointers to this would be most welcome!
Change std::vector<std::unique_ptr<Test*>> to std::vector<std::unique_ptr<Test>>.
std::unique_ptr<Test*> is a pointer to pointer (Test**).

c++ access array data of shared library

I am coding in stm32. Basically, I want to access a bool array data from another library. This is a header file of AP_Tmxk_LIDARScanner library stored data in scan.isObstacle which is a bool array. Also I made a return function named getObstacle(). Another library named AP_Tmxk_VFH to access data from getObstacle(). Is that ok? Or which is the way to copy that array in AP_Tmxk_VFH. Thanks for your help.
AP_Tmxk_LIDARScanner
class AP_Tmxk_LIDARScanner {
private:
struct{
bool isObstacle[180] = {}; //1: unsafe; 0:safe
bool available = false;
}scan;
public:
AP_Tmxk_LIDARScanner();
void init();
void update();
bool getAvailable() const{
return scan.available;
}
bool getObstacle() const{
return scan.isObstacle;
}
};
AP_Tmxk_VFH.h
class AP_Tmxk_VFH {
private:
struct{
bool Certain_Value[180] = {};
}sector;
const AP_Tmxk_LIDARScanner &_lidarscanner;
public:
// Constructor
AP_Tmxk_VFH(const AP_Tmxk_LIDARScanner &_lidarscanner);
void init();
void update();
};
AP_Tmxk_VFH.cpp
AP_Tmxk_VFH::AP_Tmxk_VFH(const AP_Tmxk_LIDARScanner &lidarscanner) :
_lidarscanner(lidarscanner)
{}
void AP_Tmxk_VFH::update()
{
if(_lidarscanner.getAvailable()){
sector.Certain_Value = _lidarscanner.getObstacle()
}
}
Here I modfiy my code format.
AP_Tmxk_LIDARScanner.h
class AP_Tmxk_LIDARScanner {
private:
struct{
bool isObstacle[180]= {}; //1: unsafe; 0:safe
bool available = false;
}scan;
public:
AP_Tmxk_LIDARScanner();
void init();
void update();
bool getAvailable() const{
return scan.available;
}
void getObstacle(int (&array)[180]);
};
AP_Tmxk_LIDARScanner.cpp
void AP_Tmxk_LIDARScanner::getObstacle(int (&array)[180])
{
for(int i=0; i<180; i++){
if(scan.isObstacle[i]){
array[i] = (array[i]+1 >= 5) ? 5 : array[i]+1;
}
else{
array[i] = (array[i]-1 >= 0) ? array[i]-1 : 0;
}
}
}
AP_Tmxk_VFH.h
class AP_Tmxk_VFH {
private:
struct{
int Certain_Value[180] = {};
}sector;
class AP_Tmxk_LIDARScanner &_lidarscanner;
public:
// Constructor
AP_Tmxk_VFH(class AP_Tmxk_LIDARScanner &_lidarscanner);
void init();
void update();
};
AP_Tmxk_VFH.cpp
AP_Tmxk_VFH::AP_Tmxk_VFH(class AP_Tmxk_LIDARScanner &lidarscanner) :
_lidarscanner(lidarscanner)
{}
void AP_Tmxk_VFH::update()
{
if(_lidarscanner.getAvailable()){
_lidarscanner.getObstacle(sector.Certain_Value);
}
}

upcasting variable in derived class c++

How to change the type of a inherited variable in the derived class?
I have the following classes:
class Position;
class StonePosition;
class Position {
public:
Position() {}
};
class StonePosition : public Position {
int count;
public:
StonePosition(const int count) { this->count = count; }
int getCount() { return this->count; }
void setCount(int count) { this->count = count; }
friend ostream& operator<<(ostream&, StonePosition);
};
class Board {
protected:
Position* crrPos;
public:
Board() { }
Position* getCrrPos() { return crrPos; }
void setCrrPos(Position* pos) { crrPos=pos; }
};
class StoneBoard : public Board {
public:
StoneBoard(const int &count) { this->crrPos=new StonePosition(count); } //<----------------
StonePosition* getCrrPos() { return (StonePosition*)crrPos; }
void setCrrPos(StonePosition* pos) { crrPos=pos; }
};
Place in which the problem is marked by an arrow. I need to change the type of a variable from Position to StonePosition in the StoneBoard class. I found an option that can be used upcasting, but it works only within a single method, and I need to change the variable for the entire class.
The problem was solved, look at my answer.
The variable "crrPos" is not of type Position it is of type pointer to Position and this is significant because a pointer to Position can point to a Position or a class derived from Position without losing anything.
If you design your classes well, and make use of virtual functions, you can usually avoid the need to upcast entirely.
#include <iostream>
class Base {
public:
virtual void foo() { std::cout << "Base::foo()\n"; }
virtual bool isDerived() const { return false; }
};
class Derived : public Base {
public:
void foo() override { std::cout << "Derived::foo()\n"; }
bool isDerived() const { return true; }
};
int main() {
Base* crrPos = new Derived;
crrPos->foo();
bool isDerived = crrPos->isDerived();
std::cout << isDerived << '\n';
delete crrPos;
}
Live demo: http://ideone.com/UKcBaA
The problem has been solved, I just use the projection ((StonePosition*)Position*):
#include <iostream>
using namespace std;
class Position;
class StonePosition;
class Position {
public:
Position() {}
};
class StonePosition : public Position {
int count;
public:
StonePosition(const int count) { this->count = count; }
int getCount() { return this->count; }
void setCount(int count) { this->count = count; }
friend ostream& operator<<(ostream&, StonePosition);
};
template <typename TPos> class TBoard {
protected:
TPos* crrPos;
public:
TBoard() { }
TPos* getCrrPos() { return crrPos; }
void setCrrPos(TPos* pos) { crrPos=pos; }
};
class Board {
protected:
Position* crrPos;
public:
Board() { }
Position* getCrrPos() { return crrPos; }
void setCrrPos(Position* pos) { crrPos=pos; }
};
class StoneBoard : public Board {
public:
StoneBoard(const int &count) { this->crrPos=new StonePosition(count); }
Position* getCrrPos() { return crrPos; }
void setCrrPos(Position* pos) { crrPos=pos; }
};
int main(){
StoneBoard s(7);
cout<<((StonePosition*)s.getCrrPos())->getCount();//<----right here
system("pause");
return 0;
}
And its working nice :)