accessing the member of a class of pointer array of another class - c++

I'm trying to figure out how I can or why I can't access the member of this class. First I'll show you what works so you know what I'm thinking, then I'll show you what I can't seem to do.
What I can do is this: I have a class with a member. I make an pointer array of that class and make NEW pieces of it (through loop) and that's fine and all. I can also make another class with a similar array and even make NEW instances of that as well and initialize them, but when I try to access them, I have problems.
This code almost works fine:
#include <iostream>
using namespace std;
class testClass{
public:
int number;
};
class testPoint{
public:
testClass testInstance;
testClass *testclassArray[5];
void makeArray();
void setToI();
};
void testPoint::makeArray(){
for (int i = 0; i < 5; i++){
testclassArray[i] = new testClass;
}
}
void testPoint::setToI(){
for (int i = 0; i < 5; i++){
(*testclassArray[i]).number = i;
}
}
int main(void){
testPoint firstTestPoint;
firstTestPoint.makeArray();
firstTestPoint.setToI();
// EXCEPT FOR THIS LINE this is where I have problems
cout << firstTestPoint.(*testclassArray[0]).number << endl;
return 0;
}
I know this should work becuase this works
int main(void){
testPoint firstInstance;
firstInstance.testInstance.number = 3;
cout << firstInstance.testInstance.number << endl;
// and this works
return 0;
}
and this works
int main(void){
testClass *testPointer[5];
for (int i = 0; i < 5; i++){
testPointer[i] = new testClass;
(*testPointer[i]).number = i;
}
cout << (*testPointer[0]).number << endl;
return 0;
}
so why can't I access the members on the cout function the same way?

The following is invalid syntax:
cout << firstTestPoint.(*testclassArray[0]).number << endl;
The most common way to write what you are trying to accomplish is:
cout << firstTestPoint.testclassArray[0]->number << endl;
But, if you prefer, you can also write:
cout << (*firstTestPoint.testclassArray[0]).number << endl;
(The second way is far less common.)
The . operator is used to access members of direct objects, e.g. a.member where a might be declared as struct A a;. The -> operator is used to access members of indirect objects (aka pointers to objects), e.g. b->member where b might be declared as struct B* b = new B();.

You are dereferencing the variable in an incorrect way.
Try doing
cout << firstTestPoint.testclassArray[0]->number << endl;
instead.
In the same way the second attempt, where it works for you, could also have been written:
out << testPointer[0]->number << endl;

Try using this code:
cout << firstTestPoint.testclassArray[0]->number << endl;

Related

How can I access an array in another class via a pointer to that array in C++?

Usually in order to access a member variable of a class/object from a different class, you would use the arrow operator (->). In this case I would like to access an array, however the size of the array is only known at runtime, therefore I can't declare the array in the header file of the class. In fact, I only declare the array in the class constructor.
I still need to be able to access this array from a different class. I'm attempting to do this by declaring a pointer in the header file of the first class, and then after the array is declared and initialised, have that pointer point to the first element of the array.
The header file station.h:
class TokenPool {
public:
TokenPool(int K);
~TokenPool();
...
public:
int K;
int *pointToPool;
};
Then in station.cpp:
TokenPool::TokenPool(int K) {
this->K = K;
cout << "K = " << this->K << " in tokenPool" << "\n";
int pool[K];
for (int i = 0; i < K; i++) {
pool[i] = i+1;
cout << pool[i] << " tokens in class " << i << "\n";
}
pointToPool = pool;
}
For the sake of simplicity let's assume that K=1.
The problem is when I attempt to access the array from a different class like so:
cout << "class " << this->k << " has " << *(station1->tokenPool->pointToPool+0) << " tokens.\n";
It produces strange output like so:
class 0 has 31156208 tokens.
Where, if K=1, it should actually show:
class 0 has 1 tokens.
Any idea what is going on?
TokenPool::TokenPool(int K) {
...
int pool[K];
...
pointToPool = pool;
}
pool is declared on the stack, so it ceases to exist as soon as the constructor returns. You assign its address to this->pool, but the address no longer points into valid memory. Subsequently reading from this pointer results in undefined behaviour.
The C++ way is generally to avoid raw arrays, and use std::vector instead. It makes the code both simpler and safer, and hardly any less efficient:
#include <vector>
class TokenPool {
public:
TokenPool(int K);
~TokenPool();
...
public:
std::vector<int> pool;
};
TokenPool::TokenPool(int K) :
pool(K)
{
cout << "K = " << this->K << " in tokenPool" << "\n";
for (int i = 0; i < K; i++) {
pool[i] = i+1;
cout << pool[i] << " tokens in class " << i << "\n";
}
}

boost multiarray as class member is not filled

I'm trying to use boost to create a multidimensional array and I want said array to be a member of some class.
However I find two problems with it:
1 - I need to declare the size of the array with
boost::extents[2][2]
Everytime I want to use the array. Otherwise I get the following error:
a.out: /usr/include/boost/multi_array/base.hpp:136: Referenceboost::detail::multi_array::value_accessor_n<T, NumDims>::access(boost::type<Reference>, boost::detail::multi_array::value_accessor_n<T, NumDims>::index, TPtr, const size_type*, const index*, const index*) const [with Reference = boost::detail::multi_array::sub_array<double, 1ul>; TPtr = double*; T = double; long unsigned int NumDims = 2ul; boost::detail::multi_array::value_accessor_n<T, NumDims>::index = long int; boost::detail::multi_array::multi_array_base::size_type = long unsigned int]: Assertion `size_type(idx - index_bases[0]) < extents[0]' failed.
2 - Ok, maybe this is just part of how multidimensional arrays work in C++ with Boost, I'm going to write my code accepting every function "declares" the array. However, if I do this I find the array is empty.
Here's a snippet of code that reproduces this problem. During the "construction" of the class the array should be filled. However, the line
cout << "Result: " << testing.getArrayMember(0,1) << endl;
outputs "Result: 0".
#include <iostream>
#include "boost/multi_array.hpp"
typedef boost::multi_array<double, 2> dbl_array;
using namespace std;
class TestClass {
public:
dbl_array darray;
TestClass(double x);
void fillArray(double x);
double getArrayMember(int i, int j);
};
TestClass::TestClass(double x) {
dbl_array darray(boost::extents[2][2]);
cout << "Class constructor called" << endl;
fillArray(x);
}
void TestClass::fillArray(double x) {
cout << "Filling array" << endl;
dbl_array darray(boost::extents[2][2]); // Without this line, the code fails at runtime
darray[0][0] = x;
darray[1][0] = 2.0*x;
darray[0][1] = 3.0*x;
darray[1][1] = 4.0*x;
cout << "Array filled" << endl;
}
double TestClass::getArrayMember(int i, int j) {
dbl_array darray(boost::extents[2][2]); // Without this line, the code fails at runtime
return darray[i][j];
}
int main() {
TestClass testing = TestClass(5.0);
// The result is 0 in the end
cout << "Result: " << testing.getArrayMember(0,1) << endl;
return 0;
}
What am I doing wrong here?
Option 1 is to use an initialisation list:
TestClass::TestClass(double x) : darray(boost::extents[2][2]) {
cout << "Class constructor called" << endl;
fillArray(x);
}
Since otherwise the member of the class darray is created using the default constructor and not through your line
dbl_array darray(boost::extents[2][2]);
as you believe.
This is the same answers as given in initialize boost::multi_array in a class
However, I want to add the following bit, which I think it is relevant in this situation:
It might be necessary for you to generate the array after performing some kind of operation in the constructor of your class. You can achieve this using "resize" after the array has been created by the default constructor.
Ie, instead of
TestClass::TestClass(double x) {
dbl_array darray(boost::extents[2][2]);
cout << "Class constructor called" << endl;
fillArray(x);
}
you could have
TestClass::TestClass(double x) {
darray.resize(boost::extents[2][2]);
cout << "Class constructor called" << endl;
fillArray(x);
}

How to access info from an instance from another instance in c++?

I am just started learning OOP concepts and to help myself learning, I have created a Characters class. From this class I have made instance called main and an instance called monster. Here is the code for the class:
#include <iostream>
#include <string>
using namespace std;
class Character {
public:
string name;
float health;
int attackLevel;
int defenseLevel;
void setAttr(string sName,float sHealth, int sAttackLevel, int sDefenseLevel) {
name = sName;
health = sHealth;
attackLevel = sAttackLevel;
defenseLevel = sDefenseLevel;
}
void attack(int whatInstanceToAttack) {
whatInstanceToAttack.hitpoints -= 20; //obviously not valid but how do i do this?
return whatInstanceToAttack;
}
int defend(string defend) {
int damageRelieved = defenseLevel * 2;
return damageRelieved;
}
};
int main() {
Character main;
Character monster;
main.setAttr("Rafael",200,100,30);
monster.setAttr("Monster1",30,40,30);
cout << "Default Values for Raf are;" << endl;
cout << main.name << endl;
cout << main.health<< endl;
cout << main.attackLevel << endl;
cout << main.defenseLevel << endl;
cout << "Default values for monster are" << endl;
cout <<monster.name << endl;
cout <<monster.health << endl;
cout << monster.attackLevel<< endl;
cout << monster.defenseLevel << endl;
return 0;
}
Basically what I want to do is somehow access the monster instance via the main instance. I want to do this by running the attack method. So if I run
main.attack(monster);
then I want the monster to lose 20 hitpoints.
How do I go about doing this?
All you need is to pass reference of Character in attack method.
I think you must be aware of pass by value and pass by reference concept. If not you can read it here
void attack(Character &whatInstanceToAttack) {
whatInstanceToAttack.hitpoints -= 20; //obviously not valid but how do i do this?
}
Yes you can access the variables of an instance from another instance of the same class. You need to use a reference to the object to ensure the changes are reflected in the other instance. So here is what your attack function should look like.
void attack(Character &c)
{
c.hitpoints - = 20;
}
Now when you call main.attack(monster) from the main() function, the hitpoints of monster will get decremented by 20.
As a side note, it is considered a good practice to make the data members of a class private, to avoid illegal access/modification of the data. Always use the member functions as an interface to your class instances.
overload the method attack and you can pass by value or reference as per your requirement.
void attack(Character chr)
or
void attack(Character &chr)

c++ how to access variable from member function?

I have a problem. I want to operate with single element of an array, which is generated in member function, but it doesn´t work. Here is my code:
using namespace std;
class Example
{
public:
int *pole;
void generate_pole();
};
void Example::generate_pole()
{
int *pole = new int [10];
for (int i = 0; i < 10; i++)
{
pole[i] = i;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
Example reference;
reference.generate_pole();
cout << reference.pole[1] << endl; //there is the problem
system("pause");
return 0;
}
How can I get an access to the element? And where is the real problem? Thank you!
int *pole = new int [10]; is creating an identically named variable pole in local scope. This is shadowing the member variable.
A fix, drop the int* from the errant line: pole = new int [10];
That said, I'd be inclined to use a constructor to set the member variable in this case: certainly you should initialise pole to nullptr by default. This is so you can delete[] pole in a destructor when an instance of your class goes out of scope. Else your code will leak memory like a colander leaks water.
An other way would be to use std::vector<int> pole; and let the C++ standard library take care of all the memory for you.
The problem is, that you shadow pole's name in the scope of the function by redeclaring it. leave the int * in front of pole behind, in generate_pole, and it should work.
An example for shadowing:
int i = 0; // i is 0
std::cout << "before scope: " << i << std::endl; // prints 0
{
int i = 1;
std::cout << "inside scope: " << i << std::endl; // prints 1
}
std::cout << "behind scope: " << i << std::endl; // prints 0

Pointers structures and dynamic memory allocation in c++

I have two structures in which the second structure has the first structure nested inside of it:
struct first
{
int a;
};
struct second
{
first nested;
};
Now the problem is that the second structure has to be dynamically allocated through a pointer. Also, the nested first structure has to be a dynamically allocated array through a pointer, whose array size has to be read in through an input file.
I know how to read it in but I don't know how to access it. For example lets suppose the size is 8. How would I go about specifying the values for the second structure given the pointer's format?
I tried assuming ptr points to first structure and ptr1 points to second structure ptr1->((ptr+count)->a) where we can process it through a loop. This doesn't work. So I was wondering how you would initialize the values the second structure whose member includes all the n structures in the n element array.
Vector is really easy just stick your struct where type is and use it like any other array. Although what you described really sounds like linked list but hey vector will probably be better for you :)
#include <vector>
//main
vector <Type> myArray(8); //set the number of elements you want
myArray[0] = blablabla
More specific example:
struct first
{
int a;
};
vector <first> myArray(8);
first[0].a = 1; // you get the idea :)
EDIT
From the comments this seems to me more up your alley.
struct bla {
int num;
};
//in main
bla *balBla = NULL;
blaBla = new(bla[8]); //There made on the fly dynamic man
blaBla[0].num = 7;
//Don't forget to delete when done or scary memory leak!!!
delete[] blaBla;
Last Edit If this is not what you want then no one will ever understand what you mean
#include <iostream>
using namespace std;
struct b {
int num;
};
struct a {
b *nested = NULL;
a(){} //Default Constructor
a(int elements) {
nested = new(b[elements]);
} //Lets you add elements to nested at initialization
void addElem(int elements) {
if (nested != NULL) {
delete[] nested;
}
nested = new(b[elements]);
} //Redefine or make new array
~a() {
delete[] nested;
} //destructor
};
int main() {
a myStupidObj(3);
myStupidObj.nested[0].num = 69;
myStupidObj.nested[1].num = 77;
myStupidObj.nested[2].num = 666;
cout << "Struct of one D array of structs" << endl;
cout << myStupidObj.nested[0].num << endl;
cout << myStupidObj.nested[1].num << endl;
cout << myStupidObj.nested[2].num << endl;
//Make 2d version
a *my2DStupidObj = new(a[2]);
my2DStupidObj[0].addElem(3);
my2DStupidObj[0].nested[0].num = 666;
my2DStupidObj[0].nested[1].num = 6969;
my2DStupidObj[0].nested[2].num = 80085;
cout << "array of struct of one D array of structs" << endl;
cout << my2DStupidObj[0].nested[0].num << endl;
cout << my2DStupidObj[0].nested[1].num << endl;
cout << my2DStupidObj[0].nested[2].num << endl;
my2DStupidObj[1].addElem(3);
my2DStupidObj[1].nested[0].num = 11;
my2DStupidObj[1].nested[1].num = 111;
my2DStupidObj[1].nested[2].num = 1111;
cout << my2DStupidObj[1].nested[0].num << endl;
cout << my2DStupidObj[1].nested[1].num << endl;
cout << my2DStupidObj[1].nested[2].num << endl;
delete [] my2DStupidObj;
return 0;
}
In C, you sometimes see something like:
struct second {
int count;
first nested[1];
};
Then, you allocate memory. The amount you allocate is computed as sizeof(struct second) plus the size of first times the number of elements you want in the array minus 1 (since there is already one included).
ptr = (struct second *)malloc(sizeof(struct second) + ((n-1) * sizeof(first)));
Then you can use
ptr->nested[idx].a
or if you have to use pointers,
((ptr->nested)+idx)->a
Of course, you have to do all the housework and cleanup yourself. C++ and its std libraries do most of that for you.