Coupling when achieve a component pattern in a c++ render - c++

Now,I hava a class with some components to do things while these components also need the reference of this parent class to update states.They coupling with each other make the design hard.Here is a example code snippet:
#include<iostream>
#include <windows.h>
#include <math.h>
using namespace std;
class man {
public:
int health{ 10 }, x, y;
void update();
private:
class moveCom *_move;
class judgeCom *_judge;
};
class moveCom {
public:
void update(man&m) {
++m.x;
++m.y;
}
};
class judgeCom {
public:
void update(man&m) {
if(rand()%10 <= 5)
++m.health;
else --m.health;
}
};
void man::update() {
_move->update(*this);
_judge->update(*this);
cout << health << " " << x << " " << y << endl;
}
int main() {
man m;
while (1) {
Sleep(200);
m.update();
}
return 0;
}
This code can only work in the same cpp file which means if split them into different hpp/cpp will cause compile error.Is there any practice to do better?
Edit:Sorry,i try it again and it okay with separate.

Related

C++ How to implement this code into the heap properly

I am working on a class assignment to create three classes nested inside each other. I need to make constructors and deconstructors for each that have a message that goes along with them. Finally, I need to create an instance of each class using new and call the display() function to show their message, followed by delete.
I have completed the assignment but in the wrong way, and I am confused about how I can properly put the code into the heap instead of the stack (as I was advised by my course tutor).
This is what I started with: (this code seems to work well, but does not fulfill the assigned project)
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
class Hen {
public:
Hen();
~Hen();
string display(void) {
return ("Im a Hen");
}
class Nest;
friend Nest;
class Nest {
public:
Nest();
~Nest();
string display(void) {
return ("Im a Nest");
}
class Egg;
friend Egg;
class Egg {
public:
Egg();
~Egg();
string display(void) {
return ("Im an egg");
}
};
};
};
Hen::Hen() {
cout << "I construct Hens" << endl;
}
Hen::~Hen() {
cout << "I deconstruct Hens" << endl;
}
Hen::Nest::Nest() {
cout << "I construct Nests" << endl;
}
Hen::Nest::~Nest() {
cout << "I deconstruct Nests" << endl;
}
Hen::Nest::Egg::Egg() {
cout << "I construct Eggs" << endl;
}
Hen::Nest::Egg::~Egg() {
cout << "I deconstruct Eggs" << endl;
}
int main() {
Hen hone;
Hen::Nest none;
Hen::Nest::Egg eone;
string h, n, e;
h = hone.display();
n = none.display();
e = eone.display();
cout << h << "\n" << n << "\n" << e << endl;
}
Where I am stuck is when I try to implement my code inside the heap, it seems to break by the second class:
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
class Hen {
public:
void display() {
cout << "Im a Hen" << endl;
}
class Nest;
friend Nest;
class Nest {
public:
void display() {
cout << "Im a Nest" << endl;
}
class Egg;
friend Egg;
class Egg {
public:
void display() {
cout << "Im an egg" << endl;
}
};
};
};
int main() {
Hen *hone = new Hen();
Hen::Nest *none = new Nest();
hone -> display();
none -> display();
}
Question 1:
If I remove all the information related to nest, the program runs Hen just fine and returns the "I'm a hen" statement. But, when I add in nest, the warning I recieve is
"error: expeected type-specifier before 'Nest'
Hen::Nest *none = new Nest();"
I do not understand what I am doing wrong as I did the exact same process for Hen and it worked. I do know that the error must be in the way Nest gets called through hen?
I apologize if this question is obvious, but I am just starting c++ and do not understand why I am getting these messages...
Thanks for your help!

Cannot instantiate abstract class?

I got this:
class Core
{
protected:
static unsigned int id_seed;
unsigned int id;
std::string status;
public:
friend class CPU;
Core();
~Core();
virtual void procesare(std::string aplicatie) = 0;
};
class CoreScreen: public Core
{
public:
CoreScreen();
~CoreScreen();
void procesare(std::string aplicatie);
};
and corescreen.cpp:
#include "CoreScreen.h"
CoreScreen::CoreScreen()
{
}
CoreScreen::~CoreScreen()
{
}
void CoreScreen::procesare(std::string aplicatie)
{
std::string buffer;
std::ifstream file_in(aplicatie);
if (file_in.is_open()) {
std::cout << "Aplicatia " << aplicatie << " ruleaza: " << std::endl;
while (getline(file_in, buffer)) {
std::cout << buffer;
}
file_in.close();
}
else {
throw new CExceptie(APP_FAIL, " Aplicatia nu a putut rula!");
}
}
When I use in main:
CoreScreen CS1, CS2, CS3, CS4;
I get this error: 'Core' cannot instantiate abstract class.
What's the problem? I thought I have my virtual function declared in CoreScreen correctly.
As I presume you know, "Core" is an abstract class, by virtue of the fact it has a pure virtual function: virtual void procesare(std::string aplicatie) = 0;.
I presume you also know that you can't instantiate an abstract class: hence your error.
The question is:
Why does the compiler think you're trying to instantiate an instance of "Core"?
Are you?
It looks like you're trying to instantiate four CoreScreen objects: CoreScreen CS1, CS2, CS3, CS4;. If so, that should be perfectly OK.
You're correct: procesare() is virtual ("pure virtual", as it happens). You've indeed overridden it correctly in CoreScreen.cpp: it DOESN'T look like that's the problem.
Q: Did you ever implement Core::Core() and Core::~Core() anywhere? If not, how did you even compile?
Q: Are you SURE you're not trying to create an instance of "Core" anywhere (even "accidentally")?
For whatever it's worth, the following MCVE compiles and runs fine (Ubuntu 18, GCC 7.3.0):
TestCore.h:
/*
* TestCore.h
*/
#ifndef TESTCORE_H_
#define TESTCORE_H_
#include <string>
class Core
{
protected:
static unsigned int id_seed;
unsigned int id;
std::string status;
public:
friend class CPU;
Core();
~Core();
virtual void procesare(std::string aplicatie) = 0;
};
class CoreScreen: public Core
{
public:
CoreScreen();
~CoreScreen();
void procesare(std::string aplicatie);
};
#endif /* TESTCORE_H_ */
TestCore.cpp:
/*
* TestCore.cpp
*/
#include <iostream>
#include <fstream>
#include "TestCore.h"
Core::Core()
{
std::cout << "Core::Core()..." << std::endl;
}
Core::~Core()
{
std::cout << "Core::~Core()..." << std::endl;
}
CoreScreen::CoreScreen()
{
std::cout << "CoreScreen::CoreScreen()..." << std::endl;
}
CoreScreen::~CoreScreen()
{
std::cout << "CoreScreen::~CoreScreen()..." << std::endl;
}
void CoreScreen::procesare(std::string aplicatie)
{
std::cout << "CoreScreen::procesare(" << aplicatie << ")" << std::endl;;
}
int main () {
std::cout << ">>main()..." << std::endl;
CoreScreen CS1, CS2, CS3, CS4;
CS1.procesare("Testing CS1");
std::cout << "<<main()." << std::endl;
return 0;
}
SAMPLE OUTPUT:
>>main()...
Core::Core()...
CoreScreen::CoreScreen()...
Core::Core()...
CoreScreen::CoreScreen()...
Core::Core()...
CoreScreen::CoreScreen()...
Core::Core()...
CoreScreen::CoreScreen()...
CoreScreen::procesare(Testing CS1)
<<main().
You'll note that I implemented Core::Core() and Core::~Core(). If you don't need them - then don't even put them in your .h class definition.
'Hope that helps

(C++) Constructor, default parameters, "call of overloaded... ambigous"

i'm new to this site, after doing some research I could not find a problem similar to mine(some questions looked like mine but their code was different)
So basically what i'm trying to do is to representing the framebuffer matrix with all different colors values. I'm coding a class named "Point", and I have one constructor, using default arguments, here it is :
Point.h
#ifndef POINT_H
#define POINT_H
#include <iostream>
class Point
{
protected:
int x;
int y;
public:
Point(int=0,int=0);
Point(const &Point);
void showC() const;
static void showC(Point);
virtual ~Point();
};
#endif // POINT_H
Point.cpp
#include "Point.h"
using namespace std;
Point::Point(int a,int b)
{
x=a;
y=b;
}
Point::~Point()
{}
void Point::showC() const
{ cout << x << " " << y << endl; }
void Point::showC(Point P)
{ cout << P.x << " " << P.y << endl; }
But the problem is when I try to compile the program
main.cpp
#include <iostream>
#include "Point.h"
using namespace std;
int main()
{
Point P1;
Point P2(2);
Point P3(4,-7);
cout << "Call of function member showC\n";
P1.showC();
P2.showC();
P3.showC();
cout << "Call of static function showC\n";
Point::showC(P1);
Point::showC(P2);
Point::showC(P3);
return 0;
}
There is an error when I create Point P2 :
"Call of overloaded 'Point(int)' is ambigous"
On all the others question i read, either it was not the same problem or they had a default constructor in addition to a constructor with default argument which cause ambiguity of which constructor to use if you create an object without argument.
On a book i'm reading to improve skills on c++, there is this sample that is working somehow, and that's why I don't really understand
Here is the sample :
main.cpp
class point
{
private :
int x;
int y;
Point (int abs=0, int ord=0) //inline constructor
{x=abs; y=ord;}
bool coincide(point);
};
bool point::coincide(point pt)
{ return ( (pt.x==x) && (pt.y==y) );
}
int main()
{
point a, b(1), c(1,0);
cout << "a and b : " << a.coincide(b) << " ou " b.coincide(a) << "\n"
cout << "b et c : " << b.coincide(c) << " ou " << c.coincide(b) << "\n"
}
However he grouped everything in the main.cpp files, and his constructor is inline.
Can anyone explain to me why is the sample working, and why my program is not ? I guess there is a mechanism that i don't understand...
Thanks in advance
RE-EDIT : I copied all the code
I think you are mixing both python and c++ way of creating class
python do use : class Point:
for declaring in class , c++ uses {} like class Point {};
Below works by changing the class declaration.
Just added a cout in your constructor
#include <iostream>
#include <vector>
using namespace std;
class Point
{
private:
int x;
int y;
public:
Point(int=0,int=0);
};
Point::Point(int a, int b)
{
x = a;
y = b;
cout<<x<<y<<endl;
}
int main()
{
Point P1;
Point P2(2);
Point P3(4,-7);
return 0;
}
Output
00
20
4-7
Program ended with exit code: 0
After question edit
Removed your buggy line and it works perfectly
Point(const &Point);
#include <iostream>
#include <vector>
using namespace std;
class Point
{
protected:
int x;
int y;
public:
Point(int=0,int=0);
//Point(const &Point);
void showC() const;
static void showC(Point);
virtual ~Point();
};
Point::Point(int a,int b)
{
x=a;
y=b;
}
Point::~Point()
{}
void Point::showC() const
{ cout << x << " " << y << endl; }
void Point::showC(Point P)
{ cout << P.x << " " << P.y << endl; }
int main()
{
Point P1;
Point P2(2);
Point P3(4,-7);
cout << "Call of function member showC\n";
P1.showC();
P2.showC();
P3.showC();
cout << "Call of static function showC\n";
Point::showC(P1);
Point::showC(P2);
Point::showC(P3);
return 0;
}
Output
Call of function member showC
0 0
2 0
4 -7
Call of static function showC
0 0
2 0
4 -7
Program ended with exit code: 0
After edit I guess you want to use copy constructor just change it to
Point(const Point &p2) {x = p2.x; y = p2.y; }

It is possible to send class reference as an argument to a function?

I stumbled across this piece of code when I researched for a good example for Observer Design pattern. In main, it gets error, taking address of temporary[-fpermissive] which I dont dont understand what it is frankly. Sending a class refference to an function? Is this real life?
#include <vector>
#include <iostream>
using namespace std;
class AlarmListener
{
public:
virtual void alarm() = 0;
};
class SensorSystem
{
vector < AlarmListener * > listeners;
public:
void attach(AlarmListener *al)
{
listeners.push_back(al);
}
void soundTheAlarm()
{
for (int i = 0; i < listeners.size(); i++)
listeners[i]->alarm();
}
};
class Lighting: public AlarmListener
{
public:
/*virtual*/void alarm()
{
cout << "lights up" << '\n';
}
};
class Gates: public AlarmListener
{
public:
/*virtual*/void alarm()
{
cout << "gates close" << '\n';
}
};
class CheckList
{
virtual void localize()
{
cout << " establish a perimeter" << '\n';
}
virtual void isolate()
{
cout << " isolate the grid" << '\n';
}
virtual void identify()
{
cout << " identify the source" << '\n';
}
public:
void byTheNumbers()
{
// Template Method design pattern
localize();
isolate();
identify();
}
};
// class inheri. // type inheritance
class Surveillance: public CheckList, public AlarmListener
{
/*virtual*/void isolate()
{
cout << " train the cameras" << '\n';
}
public:
/*virtual*/void alarm()
{
cout << "Surveillance - by the numbers:" << '\n';
byTheNumbers();
}
};
int main()
{
SensorSystem ss;
ss.attach(&Gates());
ss.attach(&Lighting());
ss.attach(&Surveillance());
ss.soundTheAlarm();
}
This is ill-formed:
ss.attach(&Gates());
^^^
Gates() is an rvalue (specifically, a prvalue). You cannot take the address of an rvalue. It's not an object that has identity, so it doesn't really have an address that you can take. The language is preventing you from doing something that doesn't make sense to do. If you did store a pointer to this temporary, you'd just end up with a dangling pointer since at the end of this line the temporary Gates would be destroyed.
Since SensorSystem doesn't own its AlarmListeners, you'll have to create them up front:
Gates gates;
Lighting lighting;
Surveillance surveillance;
SensorSystem ss;
ss.attach(&gates);
ss.attach(&lighting);
ss.attach(&surveillance);

C++ Inheritance problem

I hope I got the relevant code in here. I have some problem when I want to fetch the menu option that I've added into to menu_1. I have this function on_select(int) that I use to fetch one sub-menu's options, which I do by using the display() function. But when I compile it will say that there are no function named display() in menu_option() class, which is the Base class, but what I want to is to access the display() function which is located in the sub_menu() class.
I have tried multiple thing to get the relevant object from the array without any success, so I'm here now asking for help with this one.
I have this following main()
#include <iostream>
using namespace std;
#include "menu.h"
int main()
{
sub_menu* main_menu = new sub_menu("Warehouse Store Menu");
sub_menu* menu_1 = new sub_menu("Menu1");
main_menu->add_option(new sub_menu("Menu2"));
main_menu->add_option(menu_1);
product_menu->add_option(new add_item("sub_item1"));
product_menu->add_option(new add_item("sub_item2"));
product_menu->add_option(new add_item("sub_item3"));
main_menu->display();
main_menu->on_select(1);
delete main_menu;
return 0;
}
header file
#include <iomanip>
#include <iostream>
#include <string>
using namespace std;
const int MAX_SIZE = 9;
class menu_option
{
public:
menu_option(string const& n) : title(n) {};
virtual ~menu_option();
virtual void on_select(int) = 0;
string get_title() { return title; }
protected:
string title;
};
/* ------------------------------------- */
class sub_menu : public menu_option
{
public:
sub_menu(string const& n)
: menu_option(n) { no_item = 0; }
~sub_menu() { delete[] list; };
void on_select(int);
void add_option(menu_option*);
void display();
private:
menu_option* list[MAX_SIZE]; //container for options in the sub_menu
int no_item;
};
implement file
void sub_menu::on_select(int i)
{
cout << (list[i])->get_title() << endl;
cout << (list[i])->display() << endl; //<------ Doesn't work
}
void sub_menu::add_option(menu_option* item)
{
list[no_item] = item;
no_item++;
}
void sub_menu::display()
{
cout << ">> " << get_title() << " <<"<< endl;
for( int i = 0; i < no_item; i++ )
{
cout << setw(2) << i << ": " << (list[i])->get_title() << endl;
}
}
You can do what you want to do, but it's bad. You have to cast down to sub_menu when you call display() in on_select(). Of course it's not going to work the way you have it, and the compiler is telling you exactly why.
The other option, which is probably better (though without a clear understanding of the problem space may not be the best) would be to add display() as a virtual function to the menu_option class.
To solve your immediate problem you'll want to use dynamic_cast to turn a menu_option* into a sub_menu*, like so:
sub_menu* submenu(dynamic_cast<sub_menu*>(list[i]));
Note that if the cast fails (i.e., the menu_option pointed to by list[i] is not a sub_menu after all) the value of the submenu pointer will be NULL, so make sure you check that it is a valid pointer before using it in subsequent code.