I want opinions/views
-
Given the following code: struct SLOT { CString sField1; int nField2; }; SLOT* m_pSlots[5]; void CMyClass::InitSlots() { for (int i = 0; i < 5; i++) { m_pSlots[i] = new SLOT; if (m_pSlots[i]) { m_pSlots[i]->sField1 = "Empty slot"; m_pSlots[i]->nField2 = i; } } } Would you say it is morte correct to say that m_pSlots is a pointer to an array, or that m_pSlots is an array of pointers? My view is that it's an array of pointers, but my boss insists that it's a pointer to an array.
-
Given the following code: struct SLOT { CString sField1; int nField2; }; SLOT* m_pSlots[5]; void CMyClass::InitSlots() { for (int i = 0; i < 5; i++) { m_pSlots[i] = new SLOT; if (m_pSlots[i]) { m_pSlots[i]->sField1 = "Empty slot"; m_pSlots[i]->nField2 = i; } } } Would you say it is morte correct to say that m_pSlots is a pointer to an array, or that m_pSlots is an array of pointers? My view is that it's an array of pointers, but my boss insists that it's a pointer to an array.
-
Given the following code: struct SLOT { CString sField1; int nField2; }; SLOT* m_pSlots[5]; void CMyClass::InitSlots() { for (int i = 0; i < 5; i++) { m_pSlots[i] = new SLOT; if (m_pSlots[i]) { m_pSlots[i]->sField1 = "Empty slot"; m_pSlots[i]->nField2 = i; } } } Would you say it is morte correct to say that m_pSlots is a pointer to an array, or that m_pSlots is an array of pointers? My view is that it's an array of pointers, but my boss insists that it's a pointer to an array.
m_pSlots is an array of pointers to SLOT. One way I like to look at it, which isn't completely correct, but close enough, is to look at the contiguous storage. In your example, only the pointers are contiguous, the actual objects themselves are not. If it were an array of objects, then the physical storage to each SLOT would be contiguous (though they can be contiguous without being an array) Further examples of why it's an array of pointers is this code: >m_pSlots[i]->sField1 = "Empty slot"; >m_pSlots[i]->nField2 = i; Note that you are using the pointer dereference after the array dereference. A pointer to an array would would look like this: SLOT m_Slots[5]; SLOT* m_pSlots = m_Slots; Which would then be dereferenced as: m_pSlots[i].sField1 = "Emplty slot"; m_pSlots[i].nField2 = i; (note the use of the member dereference (.) rather than pointer dereference).
-
Aargh... the "pointers to pointers" syndrome. Without looking at a C++ reference book or looking at the compiler output, my money is on your boss. But then again...? Stroustrup will hopefully give you the correct answer...
Stroustrup (2nd edition) says that using "[]" is the same as saying "array of" and using "*" is the same as saying "pointer to". I think the interpretation of the code depends on the context in which the construct is used, and how you choose to organize it in your head. When I see this: SLOT* m_pSlots[20]; I see an array of pointers to 20 SLOT objects. This is further supported by the way the code was written to access the array: m_pSlots[0]->sField1 = "Text"; m_pSlots[0]->nField2 = 1; In the context I gave, I view it as an array of 20 pointers to SLOTs. I personally don't see how it could be logically interpreted any other way, but I do recognize the fact that you can call it a pointer to an array, but doing so obfuscates the paradigm given the context in which the code exists, IMHO.
-
Stroustrup (2nd edition) says that using "[]" is the same as saying "array of" and using "*" is the same as saying "pointer to". I think the interpretation of the code depends on the context in which the construct is used, and how you choose to organize it in your head. When I see this: SLOT* m_pSlots[20]; I see an array of pointers to 20 SLOT objects. This is further supported by the way the code was written to access the array: m_pSlots[0]->sField1 = "Text"; m_pSlots[0]->nField2 = 1; In the context I gave, I view it as an array of 20 pointers to SLOTs. I personally don't see how it could be logically interpreted any other way, but I do recognize the fact that you can call it a pointer to an array, but doing so obfuscates the paradigm given the context in which the code exists, IMHO.
Back at work and armed with stroustrup and the compiler, I think there is only corect viewpoint: yours. :cool: But talking about obfuscating code. I hope for your work buddies sake you’re not using this kind of C++-isms all over your code. Completely beside the point, of course, but what is the advantage of your piece of code over the following code (and don’t say 'memory usage' please, because I will say 'speed'...) or did you just wanted to prove your point and embarrass your boss (and me)? ;P struct SLOT { CString sField1; int nField2; }; SLOT* m_pSlots = NULL; void InitSlots() { m_pSlots = new SLOT[5]; for (int i = 0; i < 5; i++) { m_pSlots[i].sField1 = "Empty slot"; m_pSlots[i].nField2 = i; } } void DeleteSlots() { delete [] m_pSlots; } int main(int argc, char* argv[]) { InitSlots(); DeleteSlots(); return 0; }
-
Back at work and armed with stroustrup and the compiler, I think there is only corect viewpoint: yours. :cool: But talking about obfuscating code. I hope for your work buddies sake you’re not using this kind of C++-isms all over your code. Completely beside the point, of course, but what is the advantage of your piece of code over the following code (and don’t say 'memory usage' please, because I will say 'speed'...) or did you just wanted to prove your point and embarrass your boss (and me)? ;P struct SLOT { CString sField1; int nField2; }; SLOT* m_pSlots = NULL; void InitSlots() { m_pSlots = new SLOT[5]; for (int i = 0; i < 5; i++) { m_pSlots[i].sField1 = "Empty slot"; m_pSlots[i].nField2 = i; } } void DeleteSlots() { delete [] m_pSlots; } int main(int argc, char* argv[]) { InitSlots(); DeleteSlots(); return 0; }
I think memory usage would be close (if not identical) because we are talking about a given struct within a finite array. As for speed, I don't know if that would matter until we were talking about thousands of elements or hundreds/thousands or new/delete pairs. And yes, I obfuscate my code like this all the time, and no, I wasn't trying to embarass anyone. :-)
-
I think memory usage would be close (if not identical) because we are talking about a given struct within a finite array. As for speed, I don't know if that would matter until we were talking about thousands of elements or hundreds/thousands or new/delete pairs. And yes, I obfuscate my code like this all the time, and no, I wasn't trying to embarass anyone. :-)
> I think memory usage would be close (if not identical) because we are talking about a given struct within a finite array. ~ Correct. > As for speed, I don't know if that would matter until we were talking about thousands of elements or hundreds/thousands or new/delete pairs. Actually, calling X times an allocation/de-allocation routine is almost ~X times slower than calling it once with a X-time larger memory chunk (provided it doesn't trash the OS). cfr. a good OS internals book, e.g. http://www.sysinternals.com/insidew2k.htm > And yes, I obfuscate my code like this all the time, and no, I wasn't trying to embarass anyone. :-O Phew, thanks. Since we are on a roll here: Do you want to stick your neck out? Try this one: Write down the output of the listed program without compiling and running it. Then check the results... But then again, of course, you do this in a jiffy. :-D class foo { public: foo() {} virtual ~foo() {} virtual void Print(void) { cerr << "it's foo!\n"; } void Print(int err) { cerr << "it's foo with err : " << err << "\n"; } }; class childfoo1 : public foo { public: childfoo1() {} ~childfoo1() {} void Print(void) { cerr << "it's childfoo1!\n"; } void Print(int err) { cerr << "it's childfoo1 with err : " << err << "\n"; } }; class childfoo2 : public foo { public: childfoo2() {} ~childfoo2() {} void Print(void) { cerr << "it's childfoo2!\n"; } void Print(int err) { cerr << "it's childfoo2 with err : " << err << "\n"; } }; // which Print function is called ?? int main(void) { foo * foopointer1 = new childfoo1(); foo * foopointer2 = new childfoo2(); foo * foopointer3 = (childfoo1*) foopointer2; childfoo1 * foopointer4 = (childfoo1*) foopointer2; cerr << "\n1 "; foopointer1->Print(); cerr << "\n2 "; foopointer2->Print(); cerr << "\n3 "; foopointer3->Print(); cerr << "\n4 "; foopointer4->Print(); cerr << "\n5 "; foopointer1->Print(5); cerr << "\n6 "; foopointer2->Print(5); cerr << "\n7 "; foopointer3->Print(5); cerr << "\n8 "; foopointer4->Print(5); delete foopointer1; delete foopointer2; return 0; }
-
Given the following code: struct SLOT { CString sField1; int nField2; }; SLOT* m_pSlots[5]; void CMyClass::InitSlots() { for (int i = 0; i < 5; i++) { m_pSlots[i] = new SLOT; if (m_pSlots[i]) { m_pSlots[i]->sField1 = "Empty slot"; m_pSlots[i]->nField2 = i; } } } Would you say it is morte correct to say that m_pSlots is a pointer to an array, or that m_pSlots is an array of pointers? My view is that it's an array of pointers, but my boss insists that it's a pointer to an array.
Of course you are right. m_pSlots is array of pointers. Value of m_pSlots is the location of array in memory so it can be safely casted to a pointer to the array element type (in your example SLOT**). So if array declaration can be formally defined as ElementType array[TheNumberOfElement] dynamic creation can be formally defined as ElementType* array=new ElementType[TheNumberOfElement] and effectively array can be interpreted as a pointer to ElementType. Then the pointer to array must be only interpreted as a pointer to a pointer to ElementType