Let's say I define a pointer structure called date_ptr of a structure already defined, the following way:
Date *date_ptr = new Date[10]
Essentially this is an array of structures containing objects of type Date. Now let's say I wanted to set the month of each structure in the array doing:
date_ptr[0].month = new int(10);
date_ptr[1].month = new int(3);
My question is as follows: am I allowed to set the month variable of each structure using the dot operator instead of the -> even though date_ptr is a pointer to the structure. If so, does this cause any problems? Or is it better (or mandatory) to use the -> operator?
In your case, data_ptr is a pointer, but data_ptr[0] is not a pointer, but a object of type Date. Thus you can only use dot (.) but not -> to access Date's fields.
date_ptr is a pointer to structure but date_ptr[0] is a reference to a structure. That's because date_ptr[0] is the same as *(date_ptr+0). So it's mandatory to use ..
Careful, that's an array containing 0s of type Date *. In particular, the following code will segfault without proper initialization.
Anyway to answer you, -> is just syntactic sugar for equivalent code with .. You don't need to use it, you can simply write date_ptr->month=0; and it will compile. Or (date_ptr+1)->month=0; for the second element.
Do you mean the following? This would work.
Date * end_ptr = date_ptr + 10;
for (Date * ptr = date_ptr; ptr != end_ptr; ++ptr)
ptr->month = 1;
Be warned not do do this if polymorphism is involved or you'll encounter a bad surprise.
Related
i have an array of object class, and i want to assign the last indexi to NULL
i have the following code, but it gives an error
DNA is a class
allRightSequences is a vector
DNA* newDNA = new DNA[allRightSequences.size()];
newDNA [allRightSequences.size()] = NULL; << this line gives an error
NULL is a macro that, in appropriate situations, will expand into something that can be treated as a null pointer constant. So you can use it to set a pointer value:
int *ip = NULL; // okay
However, newDNA does not contain pointers; it contains objects of type DNA. Forget the array for a moment. The problem is this:
DNA dna = NULL;
This won't work, unless DNA has a constructor that can be called with whatever NULL expands into.
If you really need to have a marker at the end of the array you need to create an array of pointers. But you really don't need this. Use std::vector<DNA>, which keeps track of the size for you.
allRightSequences.size() is not the last index of an array that has allRightSequences.size() elements. The last index is allRightSequences.size() - 1. The behaviour of accessing the array out of bounds is undefined.
Another potential problem: There must exist an appropriate assignment operator in order to be assign a pointer to a DNA object. Unless you have defined such operator, the assignment is ill-formed.
What you might want (though not sure from the question yet), is an array of pointers to DNA objects.
What you are declaring is "just" an array of DNA objects; and you can't set an object to null, as Pete Becker's answer explains very well.
The following code would work:
// notice how we use +1 here to have place for the NULL element at the end
DNA* newDNA[] = new DNA*[allRightSequences.size()+1];
newDNA [allRightSequences.size()] = NULL;
For each element of the array, you'd however also have to create a DNA object via new DNA... then...
Note that if you use a compiler supporting C++11, use nullptr instead of NULL.
And if you want to avoid the hassle with pointers completely, you could use a construct like std::optional in case you use C++17 or boost::optional for earlier versions, as described in this answer to another question, as mentioned by Baum mit Augen above.
Also, the good question is what you really need that zero pointer at the end - if it's just for determining the last element when iterating over the array, then you might be better off using an std::vector<DNS> or a similar collection type instead...
Use the following code:
newDNA [allRightSequences.size()-1] = NULL;
Because an array index in C++ goes from 0 to n-1, where allRightSequences.size() in your case returns n, where n is the size of the array.
I'm given a method header as so:
char* thisMethod(char* input){}
is it possible to say,
char var = input[0];
? I know that "input" will be in the form of a char array.
I'm obviously new to C++ pointers are throwing me off. I tried researching how to work with char pointer function arguments but couldn't find anything specific enough to help. Thanks for the help.
There is a misconception that may lead you into further troubles:
I know that "input" will be in the form of a char array.
NOPE: By the scope of that function, input is a pointer to a character. The function has no way to know where such a pointer comes from.
If it has been taken from an array upon calling the function than it will be a pointer to the first element of that array.
Because pointer have an arithmetic that allows to add offsets and because the [] operator applied to pointers translates as a[b] = *(a+b) by definition, in whatever code, if a is a pointer, *a and a[0] are perfect synonymous.
Think to an array as a sequence of boxes and a pointer as your hand's index finger
adding an offset to a finger (like finger+2) means "re-point it aside" and de-referencing it (like *finger) means "look inside what it points to".
The [] operator on pointers is just a shortcut to do both operations at once.
Arrays are another distinct thing. Don't think to them when dealing with pointers, since -in more complex situations, like multidimensional array or multi-indirection pointers - the expression a[b][c] won't work anymore the same way.
There are two ways to get a value from a pointer, * and []. The following are equivalent:
char var1 = *input;
char var2 = input[0];
Using the brackets is more common when you know you were passed an array, since it allows you to supply an index. You need some way of knowing where the end of the array is so that you don't attempt any access past it, your function is missing that important detail.
As long as it's inside the function and input points to something valid ( not NULL/nullptr and not a garbage location ) then doing char var = input[0]; is just fine. It's the same as char var = *input.
P.S If it's supposed to be a string I recommend using std::string.
Today, I found out that you can write such code in C++ and compile it:
int* ptr = new int(5, 6);
What is the purpose of this? I know of course the dynamic new int(5) thing, but here i'm lost. Any clues?
You are using the comma operator, it evaluates to only one value (the rightmost).
The comma operator (,) is used to
separate two or more expressions that
are included where only one expression
is expected. When the set of
expressions has to be evaluated for a
value, only the rightmost expression
is considered.
Source
The memory address that the pointer is pointing to is initialized with a value of 6 above.
My compiler, g++, returns an error when attempting to do this.
What compiler or code did you see this in?
I believe it is bug which meant to allocate some sort of 2D array. You can't do that in C++ however. The snippet actually compiles because it's utilizing the comma operator, which returns the last expression and ignores the results of all the others. This means that the statement is equivalent to:
int* ptr = new int(6);
The 5 is ignored. this allocates an int on the heap and initializes it to (5,6).
the result of a set of statements separated by the comma operator is the value of the last statement, so the int is initialized to 6
Simply do this:
int* ptr = new int(6);
As far as comma operator is concerned, use it when you can't do the desired task without it. There is no use of applying tricks such as:
int* ptr = new int(5, 6);
This question already has answers here:
Closed 13 years ago.
Possible Duplicate:
Why does C have a distinction between -> and . ?
Lets say that I have this structure:
struct movies
{
string title;
int year;
} my_movie, *ptrMovie;
Now I access my_movie like this: my_movie.year = 1999; Now to access a pointer I must do this: ptrMovie->year = 1999;
Why do pointers use the -> operator and normal data types use the . operator? Is there any reason they couldn't both use the . operator?
The . operator accesses a member of a structure and can operate only on structure variables.
If you want to do this to a pointer, you first need to dereference the pointer (using *) and then access the member (using .). Something like
(*ptrMovie).year = 1999
The -> operator is a shorthand for this.
The . operator is only valid for a struct or class. A pointer is not a struct or class, so you need to dereference your pointer to get the struct/class it is pointing to like this
(*ptrMovie).year
The member operator . has a higher precedence than the dereference operator *, so you need to enclose the dereferencing operation in parenthesis. Or you could do this
ptrMovie->year
Both are equivalent. The '->' operator is a shortcut for dereferencing your pointer and then accessing a struct member. It is less typing and a little nicer to use in my opinion. Apparently most people agree with me because that is the standard way to access struct members from a pointer to the struct in most code that I've seen. You especially appreciate the difference when you have to do multiple levels of indirection:
ptrToStruct->memberPtr->subMemberPtr->subsubPtr->subsubsubPtr->x
(*(*(*(*(ptrToStruct).memberPtr).subMemberPtr).subsubPtr).subsubsubPtr).x
Both of those statements are equivalent, but the first is easier to work with.
If they both used . how could you differentiate between the pointer and the actual object?
To me:
->
Reminds me of an arrow which points to something, so I find it great that -> is used.
Instead of typing (*myPointer). it is simplier to use myPointer->
This question already has answers here:
What can I use instead of the arrow operator, `->`?
(7 answers)
Closed 5 years ago.
What is the difference between the dot (.) operator and -> in C++?
foo->bar() is the same as (*foo).bar().
The parenthesizes above are necessary because of the binding strength of the * and . operators.
*foo.bar() wouldn't work because Dot (.) operator is evaluated first (see operator precedence)
The Dot (.) operator can't be overloaded, arrow (->) operator can be overloaded.
The Dot (.) operator can't be applied to pointers.
Also see: What is the arrow operator (->) synonym for in C++?
For a pointer, we could just use
*pointervariable.foo
But the . operator has greater precedence than the * operator, so . is evaluated first. So we need to force this with parenthesis:
(*pointervariable).foo
But typing the ()'s all the time is hard, so they developed -> as a shortcut to say the same thing. If you are accessing a property of an object or object reference, use . If you are accessing a property of an object through a pointer, use ->
Dot operator can't be overloaded, arrow operator can be overloaded. Arrow operator is generally meant to be applied to pointers (or objects that behave like pointers, like smart pointers). Dot operator can't be applied to pointers.
EDIT
When applied to pointer arrow operator is equivalent to applying dot operator to pointee e.g. ptr->field is equivalent to (*ptr).field.
The arrow operator is like dot, except it dereferences a pointer first. foo.bar() calls method bar() on object foo, foo->bar calls method bar on the object pointed to by pointer foo.
The . operator is for direct member access.
object.Field
The arrow dereferences a pointer so you can access the object/memory it is pointing to
pClass->Field
pSomething->someMember
is equivalent to
(*pSomething).someMember
Use -> when you have a pointer.
Use . when you have structure (class).
When you want to point attribute that belongs to structure use .:
structure.attribute
When you want to point to an attribute that has reference to memory by pointer use -> :
pointer->method;
or same as:
(*pointer).method
The target.
dot works on objects; arrow works on pointers to objects.
std::string str("foo");
std::string * pstr = new std::string("foo");
str.size ();
pstr->size ();
Note that the -> operator cannot be used for certain things, for instance, accessing operator[].
#include <vector>
int main()
{
std::vector<int> iVec;
iVec.push_back(42);
std::vector<int>* iVecPtr = &iVec;
//int i = iVecPtr->[0]; // Does not compile
int i = (*iVecPtr)[0]; // Compiles.
}
It's simple, whenever you see
x->y
know it is the same as
(*x).y
The -> is simply syntactic sugar for a pointer dereference,
As others have said:
pointer->method();
is a simple method of saying:
(*pointer).method();
For more pointer fun, check out Binky, and his magic wand of dereferencing:
http://www.youtube.com/watch?v=UvoHwFvAvQE
The simplest difference between the two is that "->" dereferences a pointer before it goes to look at that objects fields, function etc. whereas "." doesn't dereference first. Use "->" when you have a pointer to an object, and use "." when you're working with the actual instance of an object.
Another equivalent way of wrinting this might be to use the dereferencing "*" on the pointer first and then just use the ".". We skip middleman by using "->".
There are other differences, but the other answers have covered this extensively.
If you have a background in Java this might confuse you, since, in Java, everything is pointers. This means that there's no reason to have symbol that doesn't dereference your pointer first. In c++ however you gotta be a little more careful with remembering what is and what isn't a pointer, and it might be a good idea to label them with the prefix "p_" or simply "p".
The . (dot) operator is usually used to get a field / call a method from an instance of class (or a static field / method of a class).
p.myField, p.myMethod() - p instance of a class
The -> (arrow) operator is used to get a field / call a method from the content pointed by the class.
p->myField, p->myMethod() - p points to a class
The -> operator is used when we are working with a pointer and the dot is used otherwise.
So if we have a struct class like:
struct class{ int num_students; int yr_grad; };
and we have an instance of a class* curr_class (class pointer), then to get access to number of students we would do
cout << curr_class->num_students << endl;
In case we had a simple class object , say class_2016, we would do
cout << class_2016.num_students << endl;
For the pointer to class the -> operator is equivalent to
(*obj).mem_var
Note: For a class, the way to access member functions of the class will also be the same way