Thread: Please explain some concepts about Pointer & Class & Array Pointer

  1. #1
    Registered User
    Join Date
    Jan 2010
    Posts
    12

    Smile Please explain some concepts about Pointer & Class & Array Pointer

    I read this code section from a tutorial, but I cannot understand it thoroughly. It is about Pointer & Class Pointer & Array Pointer.

    This is it:
    Code:
    // pointer to classes example
    #include <iostream>
    using namespace std;
    
    class CRectangle {
    	private:
    		int width, height;
    	public:
    		// prototype
    		void set_values (int,int);
    		// method
    		int area (void) {
    			return (width * height);
    		}
    };
    
    // definion
    void CRectangle :: set_values (int a, int b) {
    	width = a;
    	height = b;
    }
    
    void main () {
    	CRectangle a, *b, *c;
    	CRectangle * d = new CRectangle[2];
    	//
    	b = new CRectangle;
    	c = &a;
    	a.set_values(1,2);
    	b -> set_values(3,4);
    	d -> set_values(5,6);
    	d[1].set_values(7,8);
    	//
    	cout << "a area: " << a.area() << endl;
    	cout << "*b area: " << b -> area() << endl;
    	cout << "*c area: " << c -> area() << endl;
    	cout << "d[0] area: " << d[0].area() << endl;
    	cout << "d[1] area: " << d[1].area() << endl;
    	//
    	delete[] d;
    	delete b;	
    }
    I try to search google and understand some parts of this code. But when it contains many concepts (i.e. pointer, array, class) in the RED section, I cannot grasp the points. Many operators (*, ->, etc. ), and I failed to distinguish between them.

    Please explain it for me, especially the section in RED.

    BTW, I see the "new" operator is very different from java one, is it right?

    Thanks for any help.

  2. #2
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    These are all very fundamental topics and operators to C++, so I would suggest you try and find a better tutorial that explains all of this stuff in detail (either that or go back to previous tutorials, if you skipped any).

    "CRectangle * d = new CRectangle[2];"
    - this creates an "array" of 2 "CRectangle"s, and they will be stored in locations (using array notation) "d[0]" or "d[1]". If you dont understand arrays, then I, again, recommend going back to cover that fundamental concept.

    "d -> set_values(5,6);"
    - this is calling the function "set_values" on "d" (or equivalently, "d[0]", the first element of the "d" array). Since "d" is a reference type, you use "->" the "indirect member access" operator. Otherwise, the "dot" (".") operator is used, as you see with the non-pointer variable "a", in "a.set_values(1,2);". Nothing else special is going on.

    "d[1].set_values(7,8);"
    - this is identical to the previous line, except this is calling the function on the 1th element of the "d" array, opposed to the 0th element as in the previous line.

    "cout << "d[0] area: " << d[0].area() << endl;
    cout << "d[1] area: " << d[1].area() << endl;"
    - there are a few (basic) things going on here, which part dont you understand? A very brief description is that each line is printing the actual text "d[0] area:" (or "d[1]"), followed by the actual value returned by the called function "d[0].area()" (or "d[1].area()"). Finally, a new line is printed ("endl"). The "<<" operator basically appends or concatenates these three "things".

    The "new" operator can be thought of as "similar" to the one in Java, but this one in C++ is more of "allocating dynamic memory". When the thing you're allocating is a class, it also calls the constructor to make an object of that class. In Java, "new" is only used to create new instances of classes. In C++, it can be used on any type, including primitive types like "char" or "int". This is a very important topic and I would read much further on it or look up very basic examples.

    Again, I would suggest to go back a few tutorials that teaches and introduces these concepts slowly and incrementally. If you try and continue with this or other "complex" examples, you will become confused very, very fast. You must learn the foundation first.

  3. #3
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Quote Originally Posted by chaienbungbu View Post
    Code:
    void main () {
    	CRectangle a, *b, *c;
    	CRectangle * d = new CRectangle[2];
    	//
    	b = new CRectangle;
    	c = &a;
    	a.set_values(1,2);
    	b -> set_values(3,4);
    	d -> set_values(5,6);
    	d[1].set_values(7,8);
    	//
    	cout << "a area: " << a.area() << endl;
    	cout << "*b area: " << b -> area() << endl;
    	cout << "*c area: " << c -> area() << endl;
    	cout << "d[0] area: " << d[0].area() << endl;
    	cout << "d[1] area: " << d[1].area() << endl;
    	//
    	delete[] d;
    	delete b;	
    }
    Many operators (*, ->, etc. ), and I failed to distinguish between them.

    Please explain it for me, especially the section in RED.
    Well one thing to understand about * is that it's not an operator in the context that you highlight. d is being initialized by new in that statement. The * part is a visual cue that it is a pointer-type variable. (You could use the operator meaning to understand it and say, the expression *d is of type CRectangle.)

    Since the cout statements are confusing you should try to understand them with what you know. When * is an operator, the pointer returns the thing to which it points. Any adjustments you make, which would occur frequently when simulating arrays, have to be done first. C++ will move a pointer a certain number of bytes to reach an array element if you do addition. So d[0] and d[1] are just easier to type than *(d+0) or *(d+1). You can also access members either way: (*(d+0)).area() == d[0].area()

    It's similar for the -> operator. It is used when you have a pointer to a single object, but you need to access a member of the object to which it points. You could type (*b).area() and get the same result as b->area(). Knowing that, there is nothing stopping you from using it with an array's zero element, as *(d+0) doesn't move the pointer at all.

    In both cases it's entirely about preference and typing less.
    Last edited by whiteflags; 01-22-2010 at 03:57 PM.

  4. #4
    Registered User
    Join Date
    Jan 2010
    Posts
    12

    Smile

    Thank u very much, nadroj! One reply with many helpful suggestions for me.

    Actually, I have confusion about the operator, why "d" use with "->" but "d[1]" use with "."
    You are right to advise me to read more. I'm in a hurry to do some tasks related to my assignment. Therefore, I couldn't taste the "sweetness" of C++ ^.^

    If you have some tutorial in detail as you mentioned before, please give me. I'll read it when I have free time.

  5. #5
    Registered User
    Join Date
    Jan 2010
    Posts
    12

    Smile

    Quote Originally Posted by whiteflags View Post
    Well one thing to understand about * is that it's not an operator in the context that you highlight. d is being initialized by new in that statement. The * part is a visual cue that it is a pointer-type variable. (You could use the operator meaning to understand it and say, the expression *d is of type CRectangle.)

    Since the cout statements are confusing you should try to understand them with what you know. When * is an operator, the pointer returns the thing to which it points. Any adjustments you make, which would occur frequently when simulating arrays, have to be done first. C++ will move a pointer a certain number of bytes to reach an array element if you do addition. So d[0] and d[1] are just easier to type than *(d+0) or *(d+1). You can also access members either way: (*(d+0)).area() == d[0].area()

    It's similar for the -> operator. It is used when you have a pointer to a single object, but you need to access a member of the object to which it points. You could type (*b).area() and get the same result as b->area().

    In both cases it's entirely about preference and typing less.
    Thank whiteflags,

    Your answer explains exactly what I didn't understand.
    Last edited by chaienbungbu; 01-22-2010 at 03:59 PM.

  6. #6
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    First, your welcome.
    I'm in a hurry to do some tasks related to my assignment.
    Never a good thing! Programming certainly takes time and patience, if you rush through it (as with many things that require any brain power), it will likely be of poor quality.

    Code:
    	CRectangle * d = new CRectangle[2];
    	// ... 
    	d -> set_values(5,6);
    	d[1].set_values(7,8);
    Actually, I didnt even notice that the first one used "->" and the second one used "."! However, it seems to make sense. "d" is a pointer, so you must use the "indirect member operator" which is "->", to access any members of that thing. A "member" is something (obviously) belonging to this class, so it can be a field/global variable, function, etc. In this case its a function. The next line is accessing the 1th-element of that pointer (or "array"), so you're dereferencing the pointer to get to that 1th element. Now, this element ("d[1]") is not a pointer, so you can directly access it using the "dot" operator ("."). You do not use the "indirect" member operator ("->") because you're not indirectly accessing it--you've already dereferenced it so you're directly accessing it now. (Sorry for all the "access"es).

    If "d" was declared as "**" instead of "*", then you'd have to indirectly access the members, using "->". Hopefully this all makes sense.

    With regards to a tutorial, I dont have any specific one in mind. On this site, I imagine the tutorials are probably decent (though I havent read them). You can start here: Cprogramming.com - Programming Tutorials: C++ Made Easy and C Made Easy

  7. #7
    Registered User
    Join Date
    Jan 2010
    Posts
    12

    Smile

    Quote Originally Posted by nadroj View Post
    First, your welcome.Never a good thing! Programming certainly takes time and patience, if you rush through it (as with many things that require any brain power), it will likely be of poor quality.

    Code:
    	CRectangle * d = new CRectangle[2];
    	// ... 
    	d -> set_values(5,6);
    	d[1].set_values(7,8);
    Actually, I didnt even notice that the first one used "->" and the second one used "."! However, it seems to make sense. "d" is a pointer, so you must use the "indirect member operator" which is "->", to access any members of that thing. A "member" is something (obviously) belonging to this class, so it can be a field/global variable, function, etc. In this case its a function. The next line is accessing the 1th-element of that pointer (or "array"), so you're dereferencing the pointer to get to that 1th element. Now, this element ("d[1]") is not a pointer, so you can directly access it using the "dot" operator ("."). You do not use the "indirect" member operator ("->") because you're not indirectly accessing it--you've already dereferenced it so you're directly accessing it now. (Sorry for all the "access"es).

    If "d" was declared as "**" instead of "*", then you'd have to indirectly access the members, using "->". Hopefully this all makes sense.

    With regards to a tutorial, I dont have any specific one in mind. On this site, I imagine the tutorials are probably decent (though I havent read them). You can start here: Cprogramming.com - Programming Tutorials: C++ Made Easy and C Made Easy
    With the above explanation, now, everything is easier to understand. Thank you again, nadroj. You are a kind-hearted man ^^

  8. #8
    Registered User
    Join Date
    Jan 2010
    Posts
    12
    Hi nadroj, may I ask you one more question? As I see in some code having something like "ClassName&". I know "ClassName*" is used to declare a pointer to a class instantiation. But what is "ClassName&"? What is the difference between the "&" reference operator and this "&" in "ClassName&"?

    Thank.

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by chaienbungbu
    But what is "ClassName&"?
    Probably a reference to ClassName.

    Quote Originally Posted by chaienbungbu
    What is the difference between the "&" reference operator and this "&" in "ClassName&"?
    The address of operator is used to obtain an address; the latter is just part of the syntax of declaring a reference type.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Registered User
    Join Date
    Jan 2010
    Posts
    12
    Thank laserlight ! Your explanation is straightforward and easy to understand ^^

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by nadroj;920120"d -> set_values(5,6);"
    - this is calling the function "set_values" on "d" (or equivalently, "d[0
    ", the first element of the "d" array). Since "d" is a reference type, you use "->" the "indirect member access" operator. Otherwise, the "dot" (".") operator is used, as you see with the non-pointer variable "a", in "a.set_values(1,2);". Nothing else special is going on.
    d is not a reference type; it's a pointer type.
    References and pointers are not the same thing in C++.

    I will also give a brief explanation on the ".", "->", "*" and "[]" operators.
    On any object, we use "." operator to get access to its members. Simple.
    Now, pointers are not actual objects. They store a memory address where the actual object is stored. So it is said to "point" to the object.
    So to get to the actual object from your pointer, you must tell the compiler that "I want the object it points to", instead of the pointer. You do this by putting the "*" operator in front of it. This basically "returns" what the pointer points to.
    So to access the members of an object of which we have a pointer to, we have to first dereference it with * and then use "." to access its members.
    Unfortunately, this does not work:
    *a.set_values(1, 2);
    This is because to the compiler, it looks like first you want to access the members of a, then dereference the expression to the right of it. This is obviously not what we want, so we must tell the compiler to execute a subset of the line first, like so:
    (*a).set_values(1, 2);
    Obviously, this is nasty syntax and gets worse if you have more pointers as members you want to dereference, so a special syntax was introduced for it:
    a->set_values(1, 2);

    If we allocate an array with new, then we must obviously tell the compiler which out of all those objects we want to access, just like a normal array, so we use the "[]" operator.
    So a[0] means the 0th object (the first one in the array) and a[1] means the 1th object, and so on. Note that I say the object here, and not pointer, because when we say a[1], it's the same as writing *(a + sizeof(*a)).
    Essentially, this means "dereference the object a at the nth position from a". sizeof(*a) basically tells the compiler to return the number of bytes that an object that a points to takes up. So the "[]" dereferences the pointer because it access the nth object pointed to by this pointer, so to speak.
    Even if we allocate "just" one object by, say, d = new Rectangle(), we will always have at least one object, thus a[0] would mean the 0th object, the first and only object, the same as *a would do.
    Obviously, we can say a[10] too, and the compiler won't complain. But if we don't have 11 objects and we do this, we get undefined behavior.

    Hope this gives you insight.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #12
    Registered User
    Join Date
    Jan 2010
    Posts
    12
    Thank Elysia, after reading your post, I understand more.

  13. #13
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Quote Originally Posted by Elysia
    So a[0] means the 0th object (the first one in the array) and a[1] means the 1th object, and so on. Note that I say the object here, and not pointer, because when we say a[1], it's the same as writing *(a + sizeof(*a))
    Not quite.

    This may be the same:

    char *a = (char*)someArray;
    work( (*(a + sizeof(*someArray) * 1) );
    int *b = someArray;
    work( *(b+1) );

    But only because we are using char (the byte) as a unit of measure. In pointer arithmetic, you can add an integer directly, such as 1. In the above context it means one object after the pointer's value, which is what you want. It is true that the pointer must be moved by a certain number of addresses, but it is nothing you need to worry about.

    Just to be clear, let's look at:

    work( *(b + sizeof(*b)) );

    This moves the pointer by sizeof(*b) objects before dereferencing, which is not what you want.
    Last edited by whiteflags; 01-26-2010 at 05:18 PM.

  14. #14
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I am aware of that, but I chose not to include that. It was only to demonstrate what it does, as to not complicate matters.
    You are right, however.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  15. #15
    Registered User
    Join Date
    Jan 2010
    Posts
    6
    BTW, now I can handle Pointers moderately well. However, can u plz tell me the the pros and cons of using pointers. I asked my teacher, but he didn't know at all! ~:>

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. weird static char pointer array
    By Anator in forum C Programming
    Replies: 4
    Last Post: 11-16-2009, 07:05 AM
  2. sorting number
    By Leslie in forum C Programming
    Replies: 8
    Last Post: 05-20-2009, 04:23 AM
  3. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  4. deriving classes
    By l2u in forum C++ Programming
    Replies: 12
    Last Post: 01-15-2007, 05:01 PM
  5. Class Template Trouble
    By pliang in forum C++ Programming
    Replies: 4
    Last Post: 04-21-2005, 04:15 AM

Tags for this Thread