How to make polymorphic and static functions coexist? - c++

Or is there a way to get ResponseState::EncoderTag out of class ResponseState?
The code is shown below
#include <iostream>
#include <memory>
#include <string>
using namespace std;
class MirroredMsgRespState
{
public:
virtual ~MirroredMsgRespState(){}
virtual uint32_t encoderTag() const = 0;
};
template<typename RespMsgT, uint32_t EncoderTag>
class ErrorAndEntryResponseState : public MirroredMsgRespState
{
public:
uint32_t encoderTag() const override
{
return EncoderTag;
}
};
using ResponseState = ErrorAndEntryResponseState<int, 48>;
int main()
{
unique_ptr<MirroredMsgRespState> myResp = make_unique<ResponseState>();
cout << myResp->encoderTag() << endl; // func 1
cout << ResponseState::encoderTag() << endl; // func 2
return 0;
}
The current implementation causes the second call to report an error

You could add a static method:
#include <iostream>
#include <memory>
#include <string>
using namespace std;
class MirroredMsgRespState
{
public:
virtual ~MirroredMsgRespState(){}
virtual uint32_t encoderTag() const = 0;
};
template<typename RespMsgT, uint32_t EncoderTag>
class ErrorAndEntryResponseState : public MirroredMsgRespState
{
public:
static uint32_t getEncoderTag()
{
return EncoderTag;
}
uint32_t encoderTag() const override
{
return getEncoderTag();
}
};
using ResponseState = ErrorAndEntryResponseState<int, 48>;
int main()
{
unique_ptr<MirroredMsgRespState> myResp = make_unique<ResponseState>();
cout << myResp->encoderTag() << endl; // func 1
cout << ResponseState::getEncoderTag() << endl; // func 2
return 0;
}

Related

"Pointer to incomplete class type is not allowed"

For some reason I cannot use the "getNotify()" function attached to the "Broker" object. I added a comment to the line that is not working(in "Publisher" class). As an error I get "Error; pointer to incomplete class type is not allowed" Please help
the "Broker" class is implemented with Singleton-Pattern
Broker.h class:
#ifndef DEF_Broker
#define DEF_Broker
#include <iostream>
#include "classes.h"
using namespace std;
class Broker : Publisher
{
static Broker *instance;
Broker();
public:
static Broker* getInstance()
{
if(!instance)
{
instance = new Broker();
}
return instance;
}
void getNotify()
{
for(auto sub : SubscriberList)
{
if(t.msg == "Hello World")
{
SubCount++;
cout << SubCount << " - ";
sub->update(t.msg);
}
else if(t.msg == "Ping")
{
cout << "Ping" << endl;
sub->update("Pong");
}
}
}
};
Broker *Broker::instance = 0; // Null, because instance will be initialized on demand.
Broker::Broker(){}; // Private constructor so that no objects can be created.
#endif
classes.h :
#ifndef DEF_classes
#define DEF_classes
#include <iostream>
#include <list>
using namespace std;
class Broker;
class Subscriber
{
public:
void update(string msg)
{
cout << msg << endl;
}
};
class Topic
{
public:
string msg;
Topic(){};
Topic(string msg)
{
this->msg = msg;
}
};
class Publisher
{
protected:
list<Subscriber*> SubscriberList;
static int SubCount;
public:
Topic t;
Broker *broker;// = broker->getInstance();
Publisher(){}
Publisher(Topic t)
{
this->t = t;
};
void AddSub(Subscriber *sub)
{
SubscriberList.push_back(sub);
}
void notify(string msg)
{
broker->getNotify(); // this not working
}
};
int Publisher::SubCount = 0; // Initialize static member SubCount
#endif
Normally you would need to include broker.h in classes.h, however, this would create a circular dependency.
Therefore, implement the functions of Publisher in a .cpp file and include broker.h in that file. The forward declaration in classes.h (class broker;) needs to remain.
One possible way to solve this would be to create different files(headers and source files) for different classes. I have done this for you in this case so that you can take this example as a reference(starting point) for your future purposes/programs. Below are all the files:
Borker.h
#ifndef DEF_Broker
#define DEF_Broker
#include <iostream>
#include "Publisher.h"
class Broker : Publisher
{
static Broker *instance;
Broker();
public:
static Broker* getInstance()
{
if(!instance)
{
instance = new Broker();
}
return instance;
}
void getNotify();
};
#endif
Broker.cpp
#include "Broker.h"
#include "Subscriber.h"
Broker *Broker::instance = 0; // Null, because instance will be initialized on demand.
void Broker::getNotify()
{
for(auto sub : SubscriberList)
{
if(t.msg == "Hello World")
{
SubCount++;
std::cout << SubCount << " - ";
sub->update(t.msg);
}
else if(t.msg == "Ping")
{
std::cout << "Ping" << std::endl;
sub->update("Pong");
}
}
}
Broker::Broker()
{
}; // Private constructor so that no objects can be created.
Topic.h
#ifndef TOPIC_H
#define TOPIC_H
#include <iostream>
#include <list>
#include <string>
class Topic
{
public:
std::string msg;
Topic(){}
Topic(std::string msg);
};
#endif
Topic.cpp
#include "Topic.h"
Topic::Topic(std::string msg)
{
this->msg = msg;
}
Publisher.h
#ifndef PUBLISHER_H
#define PUBLISHER_H
#include <list>
#include "Topic.h"
class Broker;//needed for Borker *broker
class Subscriber;//needed for Subscriber*
class Publisher
{
protected:
std::list<Subscriber*> SubscriberList;
static int SubCount;
public:
Topic t;
Broker *broker;// = broker->getInstance();
Publisher(){}
Publisher(Topic t)
{
this->t = t;
};
void AddSub(Subscriber *sub);
void notify(std::string msg);
};
#endif
Publisher.cpp
#include "Publisher.h"
#include "Broker.h"//needed for broker->getNotify()
int Publisher::SubCount = 0; // Initialize static member SubCount
void Publisher::notify(std::string msg)
{
broker->getNotify(); // this not working
}
void Publisher::AddSub(Subscriber *sub)
{
SubscriberList.push_back(sub);
}
Subscriber.h
#ifndef SUBSCRIBER_H
#define SUBSCRIBER_H
#include <string>
class Subscriber
{
public:
void update(std::string msg);
};
#endif
Subscriber.cpp
#include "Subscriber.h"
#include <iostream>
void Subscriber::update(std::string msg)
{
std::cout << msg << std::endl;
}
The program compiles successfully as can be seen here.
#Ben #AnnopRana thanxs guys.
I got inspired from ur answers and i got the following solution
broker.h
#ifndef DEF_Broker
#define DEF_Broker
#include <iostream>
#include "classes.h"
using namespace std;
class Broker
{
static Broker *instance;
Broker();
public:
Publisher pub;
static Broker* getInstance()
{
if(!instance)
{
instance = new Broker();
}
return instance;
}
void getNotify()
{
for(auto sub : pub.SubscriberList)
{
if(pub.t.msg == "Hello World")
{
pub.SubCount++;
cout << pub.SubCount << " - ";
sub->Subscriber::update(pub.t.msg);
}
else if(pub.t.msg == "Ping")
{
cout << "Ping" << endl;
sub->Subscriber::update("Pong");
}
else
{
cout << "no such as topic" << endl;
}
}
}
};
Broker *Broker::instance = 0; // Null, because instance will be initialized on demand.
Broker::Broker(){}; // Private constructor so that no objects can be created.
#endif
classes.h
#ifndef DEF_classes
#define DEF_classes
#include <iostream>
#include <list>
using namespace std;
class Broker;
class Subscriber
{
public:
void update(string msg)
{
cout << msg << endl;
}
};
class Topic
{
public:
string msg;
Topic(){};
Topic(string msg)
{
this->msg = msg;
}
};
class Publisher
{
public:
list<Subscriber*> SubscriberList;
static int SubCount;
Topic t;
Publisher(){}
Publisher(Topic t)
{
this->t = t;
};
void AddSub(Subscriber *sub);
void notify(Broker *b);
};
#endif
publisher.cpp
#include "classes.h"
#include "Broker.h"//needed for broker->getNotify()
using namespace std;
int Publisher::SubCount = 0; // Initialize static member SubCount
void Publisher::notify(Broker *b)
{
b->getNotify();
}
void Publisher::AddSub(Subscriber *sub)
{
SubscriberList.push_back(sub);
}

How to work with the C++ class members individually and at the same time as a whole?

I have following C++ code
Rectangle.h
class Rectangle {
public:
Rectangle(int _id);
void draw();
int getId();
private:
int id;
};
Rectangle.cpp
#include "Rectangle.h"
#include <iostream>
Rectangle::Rectangle(int _id) {
id = _id;
}
void Rectangle::draw() {
std::cout << "Drawing rectangle with id: " << id << std::endl;
}
int Rectangle::getId() {
return id;
}
RectangleCollection.h
#include "Rectangle.h"
class RectanglesCollection {
public:
Rectangle rectangle_00;
Rectangle rectangle_01;
Rectangle rectangle_02;
Rectangle rectangle_03;
RectanglesCollection();
void update();
};
RectangleCollection.cpp
#include "RectanglesCollection.h"
RectanglesCollection::RectanglesCollection() :
rectangle_00(10),
rectangle_01(20),
rectangle_02(30),
rectangle_03(40)
{}
void RectanglesCollection::update()
{
rectangle_00.draw();
rectangle_01.draw();
rectangle_02.draw();
rectangle_03.draw();
}
main.cpp
#include "Rectangle.h"
#include "RectanglesCollection.h"
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char** argv) {
RectanglesCollection rectangles;
rectangles.update();
std::cout << "Id of the first rectangle in collection of rectangles: " << rectangles.rectangle_00.getId() << std::endl;
return 0;
}
My question is whether there is a possibility how I can avoid repeating the code inside the RectanglesCollection::update method and instead of that to use some loop iterating directly above the individual Rectangle members? It would be ideal if the user of the collection need not do anything else than define the instances of the Rectangle class. At the same time I would like to preserve the possibility to work with the Rectangle members individualy like rectangles.rectangle_00.getId().
If you represent your Rectangle member variables instead as a std::array<Rectangle, 4> in your RectanglesCollection, you can then easily access them by index and an operator[](size_t) accessor member function.
#include <array>
#include <cstddef>
#include <iostream>
#include <stdexcept>
using std::array;
using std::cout;
using std::ostream;
using std::out_of_range;
using std::size_t;
// NAME_OF for String-ify.
#define NAME_OF(x) #x
class Rectangle {
int _id;
public:
Rectangle(int id);
void draw(ostream&) const;
auto id() const -> int;
};
Rectangle::Rectangle(int id_) : _id{id_} { }
void Rectangle::draw(ostream& out) const {
out << "Drawing rectangle with id: " << id() << "\n";
}
auto Rectangle::id() const -> int {
return _id;
}
class RectanglesCollection {
array<Rectangle, 4> rectangles = {10, 20, 30, 40};
public:
auto operator[](size_t i) const -> Rectangle;
void display() const;
};
auto RectanglesCollection::operator[](size_t i) const -> Rectangle {
if (i >= rectangles.size())
throw out_of_range(NAME_OF(i));
return rectangles[i];
}
void RectanglesCollection::display() const {
for (auto&& r : rectangles) {
r.draw(cout);
}
}
int main() {
auto rectangles = RectanglesCollection();
rectangles.display();
cout << "Id of the first rectangle in collection of rectangles: " << rectangles[0].id() << "\n";
}

Having public member variables access private members of the same class in C++

I'm trying to have a class in which the function changes the value of a private members of that class but I keep getting the error of "the use of an undeclared identifier." I thought if the function is a class member then they can access the private member?
My code for reference
Building.h
#ifndef BUILDING_H
#define BUILDING_H
#include "Point2D.h"
#include "GameObject.h"
class Building : public GameObject
{
private:
unsigned int pokemon_count;
Building();
Building(char,int, Point2D);
public:
void AddOnePokemon();
void RemoveOnePokemon();
void ShowStatus();
bool ShouldBeVisible();
};
#endif
Building.cpp
#include "Building.h"
#include "GameObject.h"
#include <iostream>
using namespace std;
Building::Building()
{
display_code = 'B';
location;
id_num = ' ';
state = '0';
pokemon_count = 0;
cout << "Building default constructed";
}
Building::Building(char in_code,int in_id, Point2D in_loc)
{
id_num = in_id;
location = in_loc;
display_code = in_code;
state = '0';
cout << "Building constructed";
}
void AddOnePokemon()
{
pokemon_count = pokemon_count+1;
}
void ReturnOnePokemon()
{
pokemon_count = pokemon_count-1;
}
void ShowStatus()
{
cout << "\"(" << pokemon_count << "pokemon is/are in this building";
}
Your functions are outside the scope of your class.
Add the class name in front of the functions and this should work:
void Building::AddOnePokemon()

Implementation of static constructor in c++ doesn't work

http://ideone.com/1ohrsO
The push_back called inside the constructor of static_constructor, is not reflected. Why?
#include <iostream>
#include <vector>
#include<memory>
#include<string>
using namespace std;
class has_static_constructor
{
public:
friend class static_constructor;
static vector<int> v;
class static_constructor
{
public:
vector<int> * upt; //&v;
static_constructor()
{
cout<<"inside static_constructor";
upt = &has_static_constructor::v;
has_static_constructor::v.push_back(1);
has_static_constructor::v.push_back(20);
}
} ;
static std::unique_ptr<has_static_constructor::static_constructor> upt ;
};
unique_ptr<has_static_constructor::static_constructor> has_static_constructor::upt(new has_static_constructor::static_constructor());
vector< int > has_static_constructor::v(2,100);
int main() {
// your code goes here
for (std::vector<int>::const_iterator i = has_static_constructor::v.begin(); i != has_static_constructor::v.end(); ++i)
{ std::cout << *i << ' ';
cout<<"\n I was here\n";
}
return 0;
}
Output:
inside static_constructor100
I was here
100
I was here
static_constructor() is called before has_static_constructor::v initialization.
Move
unique_ptr<has_static_constructor::static_constructor> has_static_constructor::upt(new has_static_constructor::static_constructor());
after
vector< int > has_static_constructor::v(2,100);
to have expected behaviour.
But better avoid those global entirely.
You might want to have a look at this way of ordering the code. It removes all initialisation-order dependencies, and in my view neatly separates the public interface from the internal implementation of the static data.
#include <iostream>
#include <vector>
class has_static_constructor
{
// note - all private
struct static_data {
static_data()
: _v(2, 100)
{
_v.push_back(1);
_v.push_back(20);
}
std::vector<int> _v;
};
static static_data& statics() {
static static_data sd;
return sd;
}
// public interface
public:
static std::vector<int>& v() { return statics()._v; }
};
auto main() -> int
{
for (const auto& i : has_static_constructor::v())
{
std::cout << i << std::endl;
}
return 0;
}
expected output:
100
100
1
20

What is the proper way of passing a vector?

Im on year 10 and our teacher wants us to create an original project and using pointers
What I want to do is to create Members and be able to sort the members by there names and print them
When I run my code it says Invalid Access
Team.h
#ifndef TEAM_H
#define TEAM_H
#include "Staff.h"
#include <vector>
#include <iostream>
using std::vector;
class Team: public Staff
{
public:
Team();
~Team();
vector<Staff *> &getVector();
private:
vector<Staff *> myStaffs;
};
#endif // TEAM_H
Team.cpp
Team::Team()
{
for(unsigned int iStaff = 0; iStaff < myStaffs.size(); iStaff++)
{
myStaffs[iStaff] = createStaff(iStaff);
}
}
vector<Staff*>& Team::getVector()
{
return myStaffs;
}
Command class will do the sorting of team and print all team members
Command.cpp
void Command::printStaffs(vector<Staff*>&myStaffs)
{
for(unsigned int iStaff = 0; iStaff < myStaffs.size(); iStaff++)
{
std::cout << "Staff ID number: "<< myStaffs[iStaff]->getStaId() << std::endl
<< "Staff Skills 1: " << *myStaffs[iStaff]->getStaSkill() << std::endl
<< "Staff Skills 2: " << *myStaffs[iStaff]->getStaSkill() << std::endl
<< "Staff Skills 3: " << *myStaffs[iStaff]->getStaSkill() << std::endl
<< std::endl;
}
}
Command.h
#ifndef CommandH
#define CommandH
#include "Team.h"
#include <vector>
#include <iostream>
using std::vector;
class Command: public Team
{
public:
Command(){}
~Command(){}
void sortVector(vector<Staff* >&vectorTemp);
void printStaffs(vector<Staff* >&);
private:
vector<Staff *> vectEmployee;
};
//--------------------------------------------------------------------------
#endif
main.cpp
#include <iostream>
#include <conio.h>
#include "Team.h"
#include "Command.h"
int main()
{
Team t;
Command c;
c.printStaffs(t.getVector());
getch();
return 0;
}
Staff.h
#ifndef STAFF_H
#define STAFF_H
#include <cstdlib>
#include <ctime>
#include <string>
using std::rand;
class Staff
{
public:
Staff();
~Staff();
static Staff* createStaff(int); // creates staffs
int** getStaSkill();
int getStaId(); // returns Staff ID
static int genRanNum(int); //Generate random number
private:
int *staSkill[3];
int staId;
//int staDeptAsigned;
};
#endif
Staff.cpp
#include "Staff.h"
Staff::Staff()
{
*staSkill = new int[3];
}
Staff *Staff::createStaff(int s)
{
Staff *staff = new Staff();
staff->staId = s;
*(staff->staSkill[0]) = genRanNum(10);
*(staff->staSkill[1]) = genRanNum(10);
*(staff->staSkill[2]) = genRanNum(10);
return staff;
}
int** Staff::getStaSkill()
{
return staSkill;
}
int Staff::getStaId()
{
return staId;
}
int Staff::genRanNum(int num)
{
return 1 +(std::rand()%num);
}
Staff::~Staff(){}
When you construct a Team, you have the following constructor:
Team::Team()
{
for(unsigned int iStaff = 0; iStaff < myStaffs.size(); iStaff++)
{
myStaffs[iStaff] = createStaff(iStaff);
}
}
However, myStaffs is a member of Team and gets default constructed as empty, so nothing happens here since myStaffs.size() == 0.
Calling printStaffs on this Team::getVector() will correctly inform you that the vector is empty:
int main()
{
Command c;
Team t; // t.myStaffs will be empty
c.printStaffs(t.getVector()); // passes an empty vector to printStaffs
return 0;
}
You might want to pass a number to your Team constructor to create that many staffs:
Team::Team(int number_of_staff)
{
for(unsigned int iStaff = 0; iStaff < number_of_staff; iStaff++)
{
myStaffs.push_back(createStaff(iStaff));
}
}
int main()
{
Command c;
Team t(5); // t.myStaffs will contain 5 staff members
c.printStaffs(t.getVector()); // passes vector of 5 staff
return 0;
}