Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

CArray or vector? 1

Status
Not open for further replies.

timmay3141

Programmer
Dec 3, 2002
468
US
This is a stupid question, but I'll ask it anyway. Is it better to use MFC's CArray or STD's vector for dynamic arrays? I haven't ever used CArray before and had forgotten it even existed when I started writing a program, and so I used vector. Now that I've written quite a bit of code with vector, I saw something that mentioned CArray, and I'm wondering if it would be worth it to change my code to use CArray instead. Since this is an MFC app, I would imagine that CArray would be prefered, but is there any reason I should be aware of to use CArray over vector. I don't even know why CArray was created in the first place (if it ain't broke, don't fix it). Anyway, I'd like to hear some opinions and I'd also like to know the Hungarian notation standard with arrays. For example, which of the following be correct (or none of them):

CArray<double, double> m_adValues;
CArray<double, double> m_dValues;
CArray<double, double> m_aValues;
 
I'd choose vectors if they will work simply because they are more portable (vectors are ANSI standard C++). Even if you don't plan to compile the code on Linux or Mac, you at least have the potential to.
 
I'd use vector any time rather that CArray, reason pretty much same as BoulderBum mention, but also that I think it is easier to use.

Example:
{
std::vector<char> myString; // A string
myString.reserve(someSize+1); // Allocate space
char* sz = &myString.front(); // Now I can treat it like a simple char*

SomeReadStringFunction(sz, someSize);
}

If SomeReadStringFunction throws an exception myString will be deallocated properly with the vector's destructor,
----------
MFC has some nice portions, however I thing the design of its collection classes (CArray, CMapStringToString etc) is really terrible and un-flexible.

Also, MFC was invented before STL was part of C++ (that's probaly why we things such as CArray), so it is only &quot;natural&quot; that the STL is better...hmmm...well it is anyway :)

It is not only an issue of being portable (the windows based market is big enough for my needs anyway), but also to be generic. You can use STL's collaction classes for just about anything, while MFC's are resticted to (or designed for anyway) MFC stuff.
------
Hungarian notation? Brrrrrrr.

Hungarian notation is absolutely the WORST thing you can do to your code. There is no reason to code in type info in a variable name in C++. It was &quot;invented&quot; for cobol which is a totally different language.

Using prefix m for members, s for static members (and in theory g for glabal if we'd have one but we dont ;-) ) is sufficient.

1) What if you change from vector to, say, list? You'd then have to rename all variables using it. A task that will not improve the quality of you code one single bit. Or if you change from a pointer to a reference, or change from a pointer to an auto_ptr, of from a char* to a CString or std::string...
2) You can (or should be able to) fairly quickly decide what class some variable is:
2.1) Either it is a member (prefixed with an m)- then you can look in the class header
2.2) Or it is a local variable then it is also quite trivial since with C++ you define variables at the point where they are needed.
2.3) Or it is an in-parameter to a function which also its quite trivial to see the header of. If the function is so big you find it troublesome to find its header you probably have a problam with your design. A function should really do only one thing and do it good.
2.4) Global variables are BAD, so they are not an issue.

Or to put it like this:
If you find it troublesome to determine the type of a particular variable you probably as a design problem on a larger scale.

I must say I find at absolutely terrible to use Hungarian notation, especaially in a framework such as MFC (Microsoft has leared some and the naming guidelines for .net is clearly not Hungarian notation)

>For example, which of the following be correct (or none of them):

My answer is none.
1) No hungarian notation (see reason above)
2) vector instead of CArray (see reason above)
3) &quot;Values&quot; isn't a good name (I think) since it doesnt say what the variable really is. But since I don't really know, perhaps it is the perfect name. If so i'd call it:
std::vector<double, double> mValues;





/Per
Nerdy signatures are as lame as the inconsistent stardates of STTNG.
 
Ahem, I mean of course
std::vector<double> mValues;

[bugeyed]

/Per
Nerdy signatures are as lame as the inconsistent stardates of STTNG.
 
Thanks for your input both of you, especially PerFnurt. Have a star. Even though I personally find Hungarian notation useful because I have a really bad memory, your input is appreciated :D. Almost every book I have on MFC or win32 said Hungarian notation is good, and I suppose it really doesn't hurt even if it is bad. It would be a ton of work to take it out of all my code so far.

>What if you change from vector to, say, list?

I very rarely change a variable's type after implimenting code for the variable, so that wouldn't be a problem.

>Either it is a member (prefixed with an m)- then you can look in the class header

That takes too much time, especially if I keep forgetting (as I do sometimes). A friend and I are working on this program together, and it makes it easier if we can look at the code the other has made and immediately identify a variable's type.

>Or it is a local variable then it is also quite trivial since with C++ you define variables at the point where they are needed.

True enough in most cases. However, in this program I have a few functions that are really big, with lots of variables, and for one reason or another I cannot make it any smaller without making other, nastier functions that take about 20 parameters. I try to avoid big, complicated functions, but sometimes they are the simplest easiest way to do things, so I use tons of comments to make it clear what's going on.

>Global variables are BAD, so they are not an issue.

That brings up a good question, why exactly are they bad? I read that in a book and so I stay away from them, but it didn't say why they are bad. You see them all the time in win32 code, especially when it's using DirectX, so why are they bad in MFC?

>&quot;Values&quot; isn't a good name

Well, I didn't choose Values because it was a good name, I chose it because it was the first thing that came to mind :). I wouldn't actually name something just Values, but I couldn't think up a useful variable on the spur of the moment.
 
DOn't get me if I'm wrong but can't CArrays be sized dynamically and change its size on the fly? For example for a normal array you would have to declare how many elements you want at the start. But Carrays allow you to add elements on the fly, and delete elements on the fly. It resizes to how many elements there are.

I still recommend vectors though.

Globals are bad because sloppy programmers tend not to watch what they are doing, therefore will use the same variable in multiple places for different things, such as using a counter variable called count as a loop control, and then using the same variable count to count the records in a database say, you can see where there could be a little confusion for some poor maintenance programmer comming a long and trying to figure out what count is in this case.

 
>> >> Global variables are BAD, so they are not an issue.

>> That brings up a good question, why exactly are they bad?

It’s not so much “they are bad” but accessing them directly is bad. If you ever change or move them, all the code that was directly accessing them is broken. From an OO perspective the Singleton pattern is much more OO friendly. It’s still not a perfect solution as if you need to change the interface exposed by the class it still breaks all the code that was using it. The idea is that you mostly don’t have to change the interface even if the underlying data and/or code changes. Other Software Patterns can also be helpful, such as Factory also referred to as Resource Managers.

Like in MFC you have a global app variable but you never access it. To get the object you use AfxGetApp()



-pete
 
>I very rarely change a variable's type after implimenting code for the variable, so that wouldn't be a problem.

Wow. You mean that the initial implementation is also the final. *impressed*. With my 15 some years of sw-development I haven't yet managed to accomplish this. In my experiance stuff will need to be changed, due to a lot of things:
1) The first implementation did infact have bug.
2) I learn new better ways to solve things
3) My collegues learn new better ways to solve things
4) The requirements change.

>I try to avoid big, complicated functions, but sometimes they are the simplest easiest way to do things

If you say so, but I doubt it. Once upon a time using &quot;goto&quot; was the easiest way to do things...

I would say you have a problem with your design.
You *can* write more manageble code.

As for passing 20+ parameters...are they in some way related? Could they perhaps be encapsulated together in a class? Ie from 20+ to 1 parameter to send.

>why exactly are they [globals] bad? ... so why are they bad in MFC?

Not only in MFC. Not good at all.
With globals, everyone using that global has a dependency to it, and should it ever (God/Devil/Garlic forbid) change type for example, all using it must be updated.
------
All my rambling is about code being maintainable, easy to change, extend, remove etc. If this is not an issue for you, feel free to ignore it.

But if youre a (or aim to be) professional sw-guy such issues should be on your main focus...






/Per
Nerdy signatures are as lame as the inconsistent stardates of STTNG.
 
Globals, singletons and other &quot;external&quot; dependencies makes unit testing harder.


/Per
Nerdy signatures are as lame as the inconsistent stardates of STTNG.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top