Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I have a problem with my getters and setters in C++. I implemented a Queue, I also implememented a class Process. My queue saves processes. My class Process has two attributes: "Identifier" and "Time" and also has setters and getters. I set 80 as its Time. The problem then is that I want to modify the time to 50 and it doesn't change. I think that the problem is the Queue, but I don't know where. Heres is my fragment of code
Queue<Process> process;
Process x;
x.setIdentifier("Hi");
x.setTime(80);
process.enqueue(x);
process.getElementFront().setTime(50);
process.print();
Here is my Queue code:
class Queue{
private:
int size;
Node <L> *front;
public:
.
.
.
//front()
L getElementFront() const{
return this->front->getElement();
}
Here is my Node code:
class Node{
private:
L elem;
Node *next;
public:
.
.
.
L getElement() {
return this->elem;
}
This is my Process Class:
class Process{
private:
string identifier;
int time;
public:
Process(){
identifier = "";
time = 0;
}
string getIdentifier(){
return identifier;
}
int getTime(){
return time;
}
void setTime(int time){
this->time = time;
}
void setIdentifier(string identifier){
this->identifier = identifier;
}
friend ostream &operator<<(ostream &o, const Process &p);
};
ostream &operator<<(ostream &o, const Process &p){
o<<"Identifier: "<<p.identifier<<"\n";
o<<"Time:"<<p.time<<"\n";
return o;
}
The output of the first code is: Time = 80. I should be Time = 50, but time wasn't modified.
I believe your function "getElementFront" returns a copy of your element, So your queue will never be affected. You can write a function like "setElementFront(int)" to affect the element directly or something like this.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I'm working on a hierarchical Entity-Component System. It's called hierarchical
because an Entity might be composed of several Entities.
My hierarchy structure is implemented as several linked lists. Although, I'm not relying on several std::list or std::forward_list. Actually, I have two vectors: 1) maps an Entity to its first child; 2) maps a child to its next sibling.
I'd like to create a ranges::view on this structure, but it seems I'm forgetting something.
I'd like to use the range this way (Complete Code on GitHub):
TEST_CASE("Range adaptors")
{
auto parentSystem = System<Test::Parent>{};
auto childSystem = System<Test::Child>{};
auto parent0 = parentSystem.add();
auto parent1 = parentSystem.add();
LeftMapped<Test::Parent, System, Test::Child, System> leftMapped(parentSystem, childSystem);
leftMapped.addChild(parent0, childSystem.add());
leftMapped.addChild(parent0, childSystem.add());
leftMapped.addChild(parent0, childSystem.add());
leftMapped.addChild(parent1, childSystem.add());
// HERE \/
ranges::for_each(leftMapped.children(parent0), [](Test::Child child)
{
std::cout << static_cast<Base>(child).id() << std::endl;
});
}
And of course, make it pipeable for working with views and actions compatible with forward range (I'm not so used to the Concepts idiom).
This is the part of the code I want to adapt:
// A composition should inherit Left Mapped when it is necessary O(1) mapping from parent to children.
template <typename ParentType, template <typename> class ParentSystemType, typename ChildType, template <typename> class ChildSystemType>
class LeftMapped
{
public:
LeftMapped(ParentSystemType<ParentType>& parent, ChildSystemType<ChildType>& child):
m_firstChild(makeProperty<ChildType>(parent)),
m_nextSibling(makeProperty<ChildType>(child))
{
}
ChildType firstChild(ParentType parent) const
{
return m_firstChild[parent];
}
ChildType nextSibling(ChildType child) const
{
return m_nextSibling[child];
}
void firstChild(ParentType parent, ChildType child)
{
m_firstChild[parent] = child;
}
void nextSibling(ChildType child, ChildType next)
{
m_nextSibling[child] = next;
}
void addChild(ParentType parent, ChildType child)
{
m_nextSibling[child] = m_firstChild[parent];
m_firstChild[parent] = child;
}
// HERE \/ I don't know how to properly adapt my container.
class ChildrenView : public ranges::view_facade<ChildrenView> {
friend ranges::range_access;
const LeftMapped& mapped;
const ParentType parent;
struct cursor
{
const LeftMapped& mapped;
ChildType current;
decltype(auto) read() const
{
return current;
}
void next()
{
current = mapped.nextSibling(current);
}
bool equal(ranges::default_sentinel) const {
return current == ChildType{};
}
};
cursor begin_cursor() {
return {mapped, mapped.firstChild(parent)};
}
public:
ChildrenView() = default;
explicit ChildrenView(const LeftMapped& mapped, ParentType parent)
: mapped(mapped),
parent(parent)
{}
};
auto children(ParentType parent) const
{
return ChildrenView(*this, parent);
}
private:
Property<ParentType, ChildType, ParentSystemType> m_firstChild;
Property<ChildType, ChildType, ChildSystemType> m_nextSibling;
};
The first thing that jumped out at me was that you have reference data members both in ChildrenView and in ChildrenView::cursor. That makes those types non-assignable, which range-v3 requires. Try changing them to pointers or std::reference_wrappers, and see if that gets you any closer.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I'm writing a cheat for an offline game, and have a class called Player which is responsible for getting and setting values in another process. However, my design for this class is very poor because the use of the class Player looks very messy and ugly, very difficult to read, and maintain
// declare variables here to read
if (Player.getthis() && Player.getthat() && Player.getthat() ... and so on)
//do stuff
class Player {
...
public:
...
// either of these calls can fail, so I return TRUE on success and FALSE on failure
BOOL GetHealth(float& health);
BOOL SetHealth(float& health);
...
};
So my question is, what is a better way of doing this?
Also: I don't necessarily need to read every single value of Player in memory, only a few at a time. That is why I don't have a single method such as BOOL UpdatePlayer() which will read everything and update the player
Here is how I would do it:
class Player {
public:
class AccessException : public std::exception {
friend class Player;
public:
virtual const char *what() const noexcept {
return "Error getting property with key " + key;
}
private:
AccessException(const std::string &key)
: key(key)
{}
std::string key;
};
float GetHealth() {
if (is_error) {
throw AccessException("health");
}
return health;
}
float GetPosX() {
if (is_error) {
throw AccessException("posX");
}
return posX;
}
};
void do_stuff() {
try {
float health = player.GetHealth();
float posX = player.GetPosX();
// Use health and posX...
} catch (const AccessException &ex) {
std::cerr << ex.what() << std::endl;
}
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
As a practice program after learning C++, I am developing a text-based game. I am using object-oriented programming style for handling the worlds/their objects. Here's the necessary information about their definitions:
class Object
{
private:
unsigned int id;
public:
unsigned int getID() const { return id; }
};
class TakeableObject: public Object
{
...
};
class EdibleObject: public TakeableObject
{
private:
float healthEffect;
float staminaEffect;
public:
float getHealthEffect() const { return healthEffect; }
float getStaminaEffect() const { return staminaEffect; }
};
class Player
{
private:
float health;
float stamina;
TakeableObject inventory[256];
public:
eat(const EdibleObject* o)
{
health += o->getHealthEffect();
stamina += o->getStaminaEffect();
}
eat(int id)
{
if (inventory[id] == NULL)
throw "No item with that ID!";
eat((EdibleObject) inventory[id]);
inventory[id] = NULL;
}
};
So my question is - in Player::eat(int), is there a way I can make sure the Object at Player::inventory[id] is an EdibleObject (perhaps through exception handling?)
User dynamic cast to check the object type at runtime.
Or you can use a virtual function with default definition in parent and can update it as per your requirement in derived classes.
Instead of eat((EdibleObject) inventory[id]); use the following
EdibleObject *temp = dynamic_cast<EdibleObject *>( &inventory[id] );
if(temp) { eat(*temp); }
else { /* Handling */ }
Your code suffers Object splicing, make sure to get rid of that first.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
What is the best design for loading an object from a file? There are lots of possibilities, some of which are shown below.
class object
{
public:
object(const std::string& filename);
};
class object
{
public:
object();
void load_from_file(const std::string& filename);
};
class object
{
public:
static object load_from_file(const std::string& filename);
object(object&& an_object);
};
class object
{
public:
std::unique_ptr<object> load_from_file(const std::string& filename);
};
class object_loader
{
public:
std::unique_ptr<object> load_object_from_file(const std::string& filename);
};
and the list goes on...
Edit:
The design I went with was this:
class object
{
public:
object();
};
class object_loader
{
public:
void load_from_stream(object& an_object, std::istream& input_stream);
};
I would prefer 'class object_loader' which separates the IO loader from the container, allowing future implementation of different loaders (from txt, binary, xml ... file) without modifying original data container. Better testing possible. Also possible to remove IO from app, if no IO allowed (like embedded devices, etc).
What is the best design for loading an object from a file?
The best design usually is along these lines:
class object { public: object(); /* ... */ }; // object is default constructible
std::istream& operator >> (std::istream& in, object& o);
client code:
// from file:
std::ifstream fin(path);
object o;
fin >> o;
// from serialized string:
std::string contents = ".....";
std::istrigstream ssin(contents);
ssin >> o;
Edit:
Transactional implementation:
std::istream& operator >> (std::istream& in, object& o)
{
int i; std::string word; // example data required by object instance
if (in >> i >> word)
{ // read was successful for all data
o.set_index(i);
o.set_word(word);
}
return in;
}
// client code:
if(ssin >> o)
{ // read was successful
// use o here
} else {
// o is still as default-constructed
}
This approach will work the same also if the stream throws exceptions on errors.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I want to fill an array that's a member of a class with data. Do I have to create a function that populates it, or is there a way that I can just enter the values directly?
class example
{
private:
struct exm {
int everything[3];
};
public:
exm demo;
void output();
void populate();
};
If not would this work?
void example::populate() {
demo.everything[0] = 1;
demo.everything[2] = 1;
//and so on... (could probably use a for loop)
}
Since demo is a public member you can access it directly or you can create a member function to set values.
#include <iostream>
class example
{
private:
struct exm {
int everything[3];
};
public:
exm demo;
void output();
void populate(){
demo.everything[2] = 1;
}
};
int main()
{
example Test;
Test.demo.everything[0] = 5;
Test.populate();
std::cout<< Test.demo.everything[0]; //outputs 5
std::cout<< Test.demo.everything[2]; //outputs 1
return 0;
}
`