Page 1 of 1

Arrays Classes and C++

Posted: Sat Jan 15, 2011 12:04 am
by Alpha Omega
I have a C++ question.

Suppose you have a class Type called ClassType and AnotherClass.

Code: Select all

class AnotherClass
{
     public:
     //functions
     private:
     //members
};

class ClassType
{
      public:
    /// some functions 
     private:
     AnotherClass* classes;
};
Since the pointer to the AnotherClass class type, classes, will represent the start of an array in the constructor we write.

Code: Select all


ClassType::ClassType
{
   Another* classes = new AnotherClass[10];
}

Since you can't copy an array without setting a special function and also you wanted to overload the operator= operator we write this.

Code: Select all

ClassType::operator=(ClassType& something)
{
  classes = FunctionToCopyArray(something);
}

So in some function we could write

Code: Select all

ClassType dogs = ClassType(initialize parameters;
ClassType Kittens = dogs;
But what if you wanted to set the values of dog inside another array such as

Code: Select all


ClassType* array = new ClassType[10];
array[1] = dogs;

How would you write the operator= command for this since in my compiler the array is neither a pointer nor an object but some complicated mess?

In my case the array[1] is a private member of a third class and the function doing the equalization is a public function of that third class.

Posted: Sat Jan 15, 2011 1:20 am
by Brkopac
What are you trying to do? Keep an array of pointers to 'AnotherClass' inside of 'ClassType' then copying everything over?

Posted: Sat Jan 15, 2011 4:42 am
by Alpha Omega
Yes pretty much. My compiler keeps locking up when I try to equate class types with none copyable data members.

Posted: Sat Jan 15, 2011 6:08 am
by Arcoroc
In ClassType, are you trying to hold an array of AnotherClass, or an array of pointers to AnotherClass?
Your previous message seemed to point at the latter, but in that case your pointer to array declaration may be wrong in ClassType.

One other slight note, in

Code: Select all

ClassType::ClassType 
{ 
   Another* classes = new ClassType[10]; 
}
You probably want to write

Code: Select all

classes = new AnotherClass[10]; 
instead, lest you actually assign a local-scoped variable "classes" rather than your class-scoped "classes" member variable.

At runtime, this code will likely crash - you are going into an infinite loop calling the ClassType constructor which calls itself.

About your compiler "locking up", what does that mean? What is the message it produces?
Now given your code above, it is entirely possible that your compiler's analyzer does not catch the infinite loop and goes in a loop itself.

Posted: Sat Jan 15, 2011 6:30 am
by Alpha Omega
Sorry I fixed the OP. ClassType contains an array of AnotherClass and yes I mistyped so it should just be

classes = new AnotherClass[10];

The problem is that I have a class (A) that has an array of elements inside of another class (B) which I then am trying to copy of class (B) into a stack which is an array of class (B).

My problem is when I try to overload the 'operator=' the code that states

Code: Select all


array[1] = dogs; 

Does want to copy "dogs" which is of the ClassType class into the array which is the theoretical stack even after stating the 'operator=' overload.

**I found the problem I did not have an & in one of the member functions :x

Posted: Sat Jan 15, 2011 6:47 am
by Arcoroc
Do you have a compile error? What does it say?

Posted: Sat Jan 15, 2011 6:54 am
by Alpha Omega
Well I just found the error after a few hours of hunting. The deconstructor was deleting the array but since I didnt have an & in one of the member functions it was trying to delete an array that didnt exist anymore.

However the application is not crashing anymore but my overloaded operator is not working at all.

How do you set up an 'operator=' when the classtype involves arrays?

Posted: Sat Jan 15, 2011 9:09 am
by Brkopac
Is it necessary to overload the operator? Could you not just do something like this?

Code: Select all

class Foo {

    Data *array;

    public:

      Data *getData (int index) { return array[index]; }

};

Posted: Sat Jan 15, 2011 9:54 am
by CuteAlien
Your operator= should use a const parameter and return a reference (if you are unsure at the start, then just copy some operator from existing code). Also whenever you have an operator= you usually also want to have a copy constructor as well. And calling a function within the operator= which takes the object as parameter can be very dangerous - if you don't pass the parameter as reference in that function as that would call the copy constructor as well.

Maybe run this example (and modify and play with it):

Code: Select all

#include <cstdlib>
#include <cstdio>

class X
{
public:
	X() {}

	X(const X& x)
	{
		bar = x.bar;
		printf("copy\n");
	}

	X& operator=(const X& x)
	{
		bar = x.bar;
		printf("=\n");
		foo(x);
		fooBar(x);	// <-- very bad!
		return *this;
	}
	
	void foo(const X& x)
	{
		printf("foo\n");
	}
	
	void fooBar(X x)
	{
		printf("fooBar\n");
	}	
	
	int bar;
};

int main()
{
	X x;
	X y;
	
	y = x;
	
	return 0;
}


And just to make things a little easier. In c++ you don't have to use c-arrays, but you can use dynamic array-classes like std::vector from STL or irr::core::array from Irrlicht. So instead of
"AnotherClass* classes" you could use:

Code: Select all

irr::core::array<AnotherClass> classes;
That will do all the correct copying for you.

Posted: Sat Jan 15, 2011 3:56 pm
by Alpha Omega
Here is my code for an OBB box

Code: Select all


obbox3d& obbox3d::operator=(const obbox3d& other)
{
    other.getEdges(Edges);
    center = other.center;
    RelativeRotation = other.RelativeRotation;
    MaxEdge = other.MaxEdge;
    MinEdge = other.MinEdge;
    return *this;
}

obbox3d::obbox3d(const aabbox3d<f32>& box, IAnimatedMeshSceneNode* node)
{
    Edges = new vector3df[8];
    box.getEdges(Edges);
    updateEdges();
    center = node->getPosition();
    RelativeRotation = node->getRotation();
}

void obbox3d::getEdges(vector3df* other) const
{
    for(int i=0;i>8;i++)
    {
        other[i] = Edges[i];
    }
}

obbox3d::obbox3d(const obbox3d& other)
{
    other.getEdges(Edges);
    center = other.center;
    RelativeRotation = other.RelativeRotation;
    MaxEdge = other.MaxEdge;
    MinEdge = other.MinEdge;
}

The copying does not work I have used the copy constructor and operator=. obbox3d has an array to hold the vertices but obbox3d is a private member for an Object class there when creating an Object class I need to envoke to make a copy upon initialization. I use the same notation from Irrlicht abbox3d so I can make an obbox3d from the abbox3d.

Posted: Sun Jan 16, 2011 9:49 pm
by CuteAlien
Alpha Omega wrote: The copying does not work
"Does not work" does not tell us anything. Does it crash, where does it crash, do you have an example for the crash? Or if it does not crash - what goes wrong, how do you know it goes wrong, did you debug it, did you use debug-messages (like printf or cout)?

And don't ask for help so fast - rather learn to hunt and debug bugs yourself. You will need this all the time! Start by reducing your code to the minimal program which still goes wrong (divide and conquer!). Then figure out step by step what it really does - your debugger allows you to do just that. Find out when your operators are called (set breakpoints) and look which value each variable contains while you step through it (with VS it even will have easy dialogs for this which already show locals variable values).

Re: Arrays Classes and C++

Posted: Sun Apr 10, 2022 7:43 pm
by raymondburke
After i create an array of a class object how do i access a private member of an element of the array ??

example:
array of objects in c++
class student
{private:
int ID;
char name;

public:
get_data();
print();
};

student stan[10];

how do i access stan[2].id if i want to change that id # alone ?

I would appreciate the help.

thanks

Re: Arrays Classes and C++

Posted: Sun Apr 10, 2022 11:50 pm
by CuteAlien
You can only access private class members from functions inside that class. That's the point of using private - preventing access from outside the class.
If you want to change the variable from outside then either don't put it in private or create public member function which does the writing. Like some setID/getID functions (commonly such functions are called setters and getters).