Sign in to follow this  

You'd think I'd know pointers by now.

This topic is 4335 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have a certain class, that has a member variable that is an object of another class. The thing is, I can't predetermine how many of these objects the class has, so I have to use pointers.
class A
{
 
 public:
 int x, y;

}; 

class B
{

 public:
 A * foo;

 void SetUp(int num_foo, A * _foo);

};

void B::SetUp(int num_foo, A * _foo)
{

 foo = new B[num_foo];

 for(int index = 0; index < num_foo; index++)
 {

  foo[index]->x = _foo[index]->x;
  foo[index]->y = _foo[index]->y;

 }

}


For some reason, this isn't working. When I try to compile this, I get a message that says:
base operand of `->' has non-pointer type `FRAME'
How can it say that foo and _foo aren't pointers? When I use a "." instead of "->" the program compiled (though I didn't expect it to) however the program has runtime bugs that I haven't yet identified, which may or may not have to do with this segment of code. Edit: Fixed the code. [Edited by - uncle_rico on January 27, 2006 6:56:32 PM]

Share this post


Link to post
Share on other sites
Inside class B I assume you are meaning to reference a pointer to class A?

Also, you syntax for for-loops is incorrect. it should be (initialize; test-for-completion; increment). You have the second and third parts backwards.

So:


class B
{
public:
A * foo;

void SetUp(int num_foo, A * _foo);
};

void B::SetUp(int num_foo, A * _foo)
{
foo = new A[num_foo];

for(int index = 0; index < num_foo; index++)
{
foo[index]->x = _foo[index]->x;
foo[index]->y = _foo[index]->y;
}
}



It would also be worth validating your input to SetUp. That is, check num_foo is greater than zero and check that _foo isn't NULL;

Alan

Share this post


Link to post
Share on other sites
The [] operator automatically dereferences the pointer. In other words, this:

foo[index]->x = _foo[index]->x;


should be:

foo[index].x = _foo[index].x;


because, although 'foo' may be a pointer, 'foo[index]' is not.

Share this post


Link to post
Share on other sites
Hi,

Been a while since I last typed C :) . But something looks odd. An array is stored like a pointer, right? (Hence char *a = [ 'a', 'b' ]; or something like that) So isn't the access of one array element a non-pointer operation (ie. the pointer is to the array not the element, otherwise you'd do " = new B*;" or something like that :) ). Can anyone clear this out? Thanks,

JVFF

Share this post


Link to post
Share on other sites
Quote:
Original post by jvff
Hi,

Been a while since I last typed C :) . But something looks odd. An array is stored like a pointer, right? (Hence char *a = [ 'a', 'b' ]; or something like that) So isn't the access of one array element a non-pointer operation (ie. the pointer is to the array not the element, otherwise you'd do " = new B*;" or something like that :) ). Can anyone clear this out? Thanks,

JVFF


Actually, it is a pointer operation. Look:

float xyz[] = {1.0f, 1.0f, 1.0f}; // Some array :D

//This:
xyz[1] += xyz[0];

//Is equivalent to:
(*(xyz + 1)) += (*xyz);



All operator[] does on an array is return a NON pointer to the object, just the way I showed you above.

An array name is always a pointer to the first element, which means that:

float doStuff(float *x) {
*x = 1.0f;

return *x;
}

//Later on:
doStuff(xyz);



Is perfectly valid, you're passing a pointer to the first element. So, *x in that case is *xyz, or xyz[0].

This is ok too:

bool ABunchOfCrap[1000] = {false};

ABunchOfCrap += 500;



What that does is increase the pointer ABunchOfCrap(remember, it points to the first element) to point to new elements. This way, *ABunchOfCrap isn't ABunchOfCrap[0], but rather ABunchOfCrap[500]. Understand?

If you have questions, ask!

Good luck!

Share this post


Link to post
Share on other sites
i would recommend using stl class vector, it will make your code more reabable and less bug prone:


#include <vector>

//class A

class B
{

public:
std::vector<A>;

void SetUp(const vector<A>);

};

void B::SetUp(const vector<A> inputVector )
{
foo = inputVector;
}



you can use your class in exaclty the same way:

vector<A> v;
v.push_back( A() );
B b;
b.SetUp( v );
b.foo[7].x = 42;
//and you can use this for the number of elements
b.foo.size();



also be warned, public variables are to be avoided if possible

Share this post


Link to post
Share on other sites

#include <iostream>

using namespace std;

class A{
public:
int x,y;

A(){ x=1,y=2 ; };

};

class B{
public:
A* AObject;

void SetUp(int num);
};

void B::SetUp(int num){
if(num){
AObject = new A[num];
if(AObject){
for (int i=0; i<num; i++){
AObject[i].x = 10;
AObject[i].y = i+10;
}
AObject->x = 100;
AObject[1].x = 100;
}
}
}

int main(){
B bclass;
bclass.SetUp(5);
for(int i=0;i<5;i++)
cout << "x= " << bclass.AObject[i].x << " y = " << bclass.AObject[i].y << endl;
return 0;
}


What you see above might explain the issue...
Inside B::Setup , i initialize the x and y so that the receive new values...
After the loop i input a couple different values ( to show the difference between the two operators) into the
first object of the AObject array :
AObject->x = 100;

second Abject:
AObject[1].x = 100;

It works for the 'AObject->x = 100' because, the name of the array is considered to be a pointer so you can use the '->' operator, the AObject[1] uses the '.' operator, cause it is a class access not pointer access. I hope that shines some light on the topic ...

The pointer '->' operator would work on the array access:
AObject[index]->x = 100;
if you had an array of pointers to A class not a pointer to and array of A objects ...



Share this post


Link to post
Share on other sites
Quote:
Original post by agi_shi
Actually, it is a pointer operation. Look:
*** Source Snippet Removed ***
All operator[] does on an array is return a NON pointer to the object, just the way I showed you above.

An array name is always a pointer to the first element, which means that:
*** Source Snippet Removed ***
Is perfectly valid, you're passing a pointer to the first element. So, *x in that case is *xyz, or xyz[0].

This is ok too:
*** Source Snippet Removed ***
What that does is increase the pointer ABunchOfCrap(remember, it points to the first element) to point to new elements. This way, *ABunchOfCrap isn't ABunchOfCrap[0], but rather ABunchOfCrap[500]. Understand?

If you have questions, ask!

Good luck!


Um... That's what I meant. That accessing an array element returns the value, because the array is stored like a pointer. I should stop posting at 5am :D . Sorry about any confusion,

JVFF

Share this post


Link to post
Share on other sites
Quote:
Original post by jvff
Hi,

Been a while since I last typed C :) . But something looks odd. An array is stored like a pointer, right? (Hence char *a = [ 'a', 'b' ]; or something like that) So isn't the access of one array element a non-pointer operation (ie. the pointer is to the array not the element, otherwise you'd do " = new B*;" or something like that :) ). Can anyone clear this out? Thanks,

JVFF


Oh.. I thought that you meant the bolded.

You can have pPointer = new What*. It depends if you have a double pointer: whatever **pPointer. If I'm correct, a pointer is stored on the stack, so you can create pointers on the heap and access those pointers with pointers on the stack. Too bad you can't create a pointer on the heap that points to a pointer on the heap. Maybe you can, but you still need a stack pointer to point to the heap pointer.

Share this post


Link to post
Share on other sites

This topic is 4335 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this