Modifying an object also modifies all other objects of the same class - c++

It's a long time ago since my last c++ project and now I'm stuck in a very simple problem. I create two objects and want to modify only one of them. Now I don't understand why the other object is also modified...
MainClass:
#include "testobject.h"
#include <iostream>
int main() {
TestObject o1;
TestObject o2;
std::cout << "object1 before: " << o1.getI() << std::endl;
std::cout << "object2 before: " << o2.getI() << std::endl;
o1.setI(2);
std::cout << "object1 after: " << o1.getI() << std::endl;
std::cout << "object2 after: " << o2.getI() << std::endl;
}
TestObjectClass:
#include "testobject.h"
int i;
int TestObject::getI() {
return i;
}
void TestObject::setI(int j) {
i = j;
}
The output is:
object1 before: 0
object2 before: 0
object1 after: 2
object2 after: 2
Why is i in object2 also set to 2?

The both objects refer to the common variable
int i;
declared in the global namespace. So once the variable is changed the class method
int TestObject::getI() {
return i;
}
will return the same value of the variable i for both objects.
Make the variable a data member of the class.
For example
class TestObject
{
//...
private:
int i;
};
Pay attention to that the member function getI should be declared with the qualifier const because it does not change the object itself
class TestObject
{
public:
int getI() const {
return i;
}
//...
};

Related

Integer pointer only has correct value if I print it

I am implementing my own smart_pointer, which counts the references to the thing it points to. Here is my implementation so far:
#pragma once
#include <iostream>
template <typename T>
class smart_pointer{
T* pointer;
int* cnt;
public:
smart_pointer<T>(T *el): pointer(el) { int i = 1; cnt = &i; }; //
smart_pointer<T>(const smart_pointer<T>& other): pointer(other.pointer) {
// std::cout << ", *(other.cnt): " << *(other.cnt);
cnt = other.cnt;
(*cnt)++;
} // Copy-constructor
int counter(){
int c = *cnt;
return c;
}
};
In main.cpp, I did the following:
int main(){
// smart_pointer_examples();
std::string h("hello");
smart_pointer<std::string> p(&h);
std::cout << "p: " << p.counter();
smart_pointer<std::string> q(p);
std::cout << ", q: " << q.counter() << std::endl;
return 0;
}
The problem is that that outputs p: 1, q: 6487781. After a lot of time trying to find the issue by debugging and printing stuff, I found something that fixed my issue: By adding std::cout << ", *(other.cnt): " << *(other.cnt); somewhere in my copy-constructor, the output becomes p: 1, *(other.cnt): 1, q: 2, which is the desired behaviour. I can't for the life of me think of why printing the counter would change anything.
Edit: Also, if I only do *(other.cnt) without std::cout, the same problem that I started with happens.
You made a small mistake in implementing your idea.
I will not comment on the design of your smart pointer implementation.
The problem is that you implemented your counter as a pointer. That is wrong.
And, you are dereferencing a local variable. That is a semantic bug. The result is undefined. The value of the counter will be indeterminate. Additionally you should initialize your class members.
If we fix both, then your code will look like:
#pragma once
#include <iostream>
template <typename T>
class smart_pointer {
T* pointer{};
int cnt{};
public:
smart_pointer<T>(T* el) : pointer(el) { cnt = 1; }; //
smart_pointer<T>(const smart_pointer<T>& other) : pointer(other.pointer) {
// std::cout << ", *(other.cnt): " << *(other.cnt);
cnt = other.cnt;
cnt++;
} // Copy-constructor
int counter() const {
return cnt;
}
};
int main() {
// smart_pointer_examples();
std::string h("hello");
smart_pointer<std::string> p(&h);
std::cout << "p: " << p.counter();
smart_pointer<std::string> q(p);
std::cout << ", q: " << q.counter() << std::endl;
return 0;
}

(C++) How to redefine "=" operator for object

I have an object of class A.
class A[
{
int x;
string y;
float z;
....
}
Then I have an int, called "integer".
How can I redefine the = operator in order to do something like
int integer;
A obj = integer;
in order to obtain something equal to the constructor call with NOT all members:
A obj(integer,",0);
This is a little naughty, but:
#include <iostream>
using std::cout;
using std::endl;
class A {
public:
int x;
A & operator=(int value) {
x = value;
return *this;
}
};
int main(int, char **) {
A obj;
obj.x = 5;
cout << "Initially: " << obj.x << endl;
obj = 10;
cout << "After: " << obj.x << endl;
}
When run:
g++ Foo.cpp -o Foo && Foo
Initially: 5
After: 10
Is this what you're trying to do? Note that this is very naughty. class A is NOT an integer, and assigning it to an int is going to confuse people. C++ lets you do things that you probably shouldn't do, and this is one of them.

Cocos2dx Style and Implementation

I'm sort of getting back into cocos2dx development. This time I would like to fully understand the subtleties of the library. I have begun to get a good understanding of singleton classes, which they use throughout. I do have a question about their implementation. Here is a basic example of a singleton class being used
class GlobalClass
{
int m_value;
public:
GlobalClass(int v = 0)
{
m_value = v;
}
int get_value()
{
return m_value;
}
void set_value(int v)
{
m_value = v;
}
};
// Default initialization
GlobalClass *global_ptr = 0;
void foo(void)
{
// Initialization on first use
if (!global_ptr)
global_ptr = new GlobalClass;
global_ptr->set_value(1);
cout << "foo: global_ptr is " << global_ptr->get_value() << '\n';
}
void bar(void)
{
if (!global_ptr)
global_ptr = new GlobalClass;
global_ptr->set_value(2);
cout << "bar: global_ptr is " << global_ptr->get_value() << '\n';
}
int main()
{
if (!global_ptr)
global_ptr = new GlobalClass;
cout << "main: global_ptr is " << global_ptr->get_value() << '\n';
foo();
bar();
}
My question is about the initialization that comes after class definition and before foo, bar, and main. Essentially, I am interested in this line
GlobalClass *global_ptr = 0;
Where is the stack instance being initialized? You need some interface for that global pointer to the heap that is the member of that stack instance, right? If so, where is this done in cocos2dx?
My other question is about the use of the scope resolution operator (::) to call methods such as in
glview = GLViewImpl::create("MyView")
What purpose does this serve? Is this to overstep name spacing to access singleton instances?
If any of my understandings are wrong, especially on singletons, please correct them.
I think Syntax of your Singleton class is wrong.
It should be like this :
class GlobalClass
{
static GlobalClass* _instance; // Make private so only can access with method to avoid NPE for first time access
GlobalClass(int v = 0) // Make constructor private, you can't create object outside the class
{
m_value = v;
}
int m_value;
public:
static GlobalClass* getInstance();
int get_value()
{
return m_value;
}
void set_value(int v)
{
m_value = v;
}
};
GlobalClass* GlobalClass::_instance = 0;
GlobalClass* GlobalClass::getInstance() {
return GlobalClass::_instance == nullptr ? GlobalClass::_instance = new GlobalClass : GlobalClass::_instance;
}
void foo(void)
{
auto global_ptr = GlobalClass::getInstance();
global_ptr->set_value(1);
std::cout << "foo: global_ptr is " << global_ptr->get_value() << '\n';
}
void bar(void)
{
auto global_ptr = GlobalClass::getInstance();
global_ptr->set_value(2);
std::cout << "bar: global_ptr is " << global_ptr->get_value() << '\n';
}
int main()
{
auto global_ptr = GlobalClass::getInstance();
std::cout << "main: global_ptr is " << global_ptr->get_value() << '\n';
foo();
bar();
system("pause");
return 0;
}
And your second question :
Why we use or having static method create() almost in all class of cocos2d-x
In cocos2d-x we create object in two phase
- Create Object // No game Logic only set default_values
- Initialize Object
We're using Reference Count mechanism for memory management in cocos2d-x. what is it ?
These 2-phase constructor and auto-released reference count together into a static function: create()

Concept of data storing in c++

I have a Spieler class and a Verein class with a vector of Spieler members.
Now if I change something of the Players like the Staerke(german for strength) by using a function of this class in the player class it does not automatically change the value for this player.
Here is the code:
#include <vector>
#include<iostream>
#include <string>
using namespace std;
class Spieler
{
public:
void setinformation(int a, string b, string c, int d)
{
ID = a;
Vorname = b;
Nachname = c;
Staerke = d;
}
void getinformation()
{
cout << "ID: " << ID << endl;
cout << "Vorname: " << Vorname << endl;
cout << "Nachname: " << Nachname << endl;
cout << "Staerke: " << Staerke << endl << endl;
}
void setStaerke(int x)
{
Staerke = x;
}
int getStaerke()
{
return Staerke;
}
private:
string Vorname, Nachname;
int Staerke, ID;
};
class Verein
{
public:
void setSpielerListe(vector<Spieler> x)
{
Spielerliste = x;
}
vector<Spieler> getSpielerListe()
{
return Spielerliste;
}
string getVereinsName()
{
return VereinsName;
}
int getVereinsID() const
{
return VereinsID;
}
void setVereinsID(int x)
{
VereinsID = x;
}
int getGesamtstaerke()
{
Gesamtstaerke = 0;
vector<Spieler> b;
b = getSpielerListe();
for (size_t i = 0; i < b.size(); i++)
{
Gesamtstaerke = Gesamtstaerke + b[i].getStaerke();
}
return Gesamtstaerke;
}
void Vereinsinformationen()
{
vector<Spieler> list;
int id;
string vereinsname;
int gesamtstaerke;
id = getVereinsID();
vereinsname = getVereinsName();
gesamtstaerke = getGesamtstaerke();
list = getSpielerListe();
cout << "VereinsID: " << id << endl;
cout << "Vereinsname: " << vereinsname << endl;
cout << "Gesamstaerke: " << gesamtstaerke << endl << endl;
cout << "Spieler: " << endl;
for (size_t i = 0; i < list.size(); i++)
list[i].getinformation();
}
private:
vector<Spieler> Spielerliste;
int VereinsID, Gesamtstaerke;
string VereinsName;
};
vector<Spieler> spieler;
int main()
{
Spieler Spieler1;
Spieler1.setinformation(0, "Peter", "Pan", 10);
spieler.emplace_back(Spieler1);
Verein Team1;
Team1.setSpielerListe(spieler);
Spieler1.setStaerke(20);
Team1.Vereinsinformationen();
cin.get();
return 0;
}
I'm really new into c++ and programming so the code might be terrible.
Guess it has to do with pointers, I'm really not into the concept of storing data in c++, try to get it by trial & error; So how to change the Staerke in a way that it is changed in the Teams Playerlist too?
The problem is you are storing full object in the vector and not pointers. When you run this line:
spieler.emplace_back(Spieler1);
a copy of Spieler1 is made and put in the vector. So modifying it in the main will have no effect in the vector. Also not that you are copying the vector when setting in Verein class.
You should use pointer if this is what you are after or better yet have a function to modify strength from Verein class taking its id and new strength as parameters might be a good idea. Something like this:
void setStaerke(int id, int x)
{
vector<Spieler>::iterator it = Spielerliste.begin();
while (it != Spielerliste.end())
{
if ((*it).GetId() == id)
{
(*it).setStaerke(x);
break;
}
}
}
If you have access to C++11, it could be made more elegantly.
Hereby you pass and store a copy from the vector into the object:
Team1.setSpielerListe(spieler);
Therefore changes to the original vector and the contained objects will not affect the member.
Further, I don't have much experience with emplace_back, but the more usual way to append an object to a std::vector would also append a copy:
spieler.push_back(Spieler1);
Therefore changes to the original object would not affect the object you've appended to the container.
Make sure you better understand when objects are copied.
For reference:
http://en.cppreference.com/w/cpp/container/vector/emplace_back
http://en.cppreference.com/w/cpp/container/vector/push_back
How to pass objects to functions in C++?

c++ Passing a value the wrong way?

When i am passing an object to a function, I am getting undesired results. It seems to happen when I pass a Character through a Mage's action() function.
Here are some snippits of my code:
character.h
class Character {
public:
Character();
int getMaxLives() const;
int getMaxCraft() const;
protected:
maxLives;
maxCraft;
};
character.cpp
#include "character.h"
Character::Character () {
maxLives = 5;
MaxCraft = 10;
}
int Character::getMaxLives() const {
return maxLives;
}
int Character::getMaxCraft() const {
return maxCraft;
}
mage.h
#include "character.h"
class Mage {
public:
Mage();
void action(Character c1);
};
mage.cpp
#include "mage.h"
Mage::Mage () { ... }
void Mage::action(Character c1) {
cout << "Max Craft: " << c1.getMaxCraft() << endl;
cout << "Max Lives: " << c1.getMaxLives() << endl;
}
driver.cpp
int main () {
Character c1;
Mage m1;
m1.action(c1);
My ouput gives me the following:
Max Craft: 728798402 (The number varies)
Max Lives: 5
However, if in my diver, i do:
cout << "Max Craft: " << c1.getMaxCraft() << endl;
cout << "Max Lives: " << c1.getMaxLives() << endl;
I get:
Max Craft: 10
Max Lives: 5
Any ideas?
Looks like you meant for MaxCraft = 10; (in your default constructor) to actually be maxCraft = 10;. As #chris says in the comments, it appears that you're using some (evil, evil) C++ extension that allows implicitly-typed variables, so the MaxCraft = 10; line is simply defining a new variable named MaxCraft.