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!

Need help on simple return types from functions 3

Status
Not open for further replies.

Flappy

Programmer
Jul 30, 2002
35
AU
I've got some questions about return types from functions...

I've written a few programs now in C++ and they are working fine but I'm not sure if they are really programmed properly or not. The only issue that I'm faced with is am I returning valid values/objects that are safe?

Like is it safe to return a string object from a function? Is it safe to return an object from a function? As I know it isnt safe to return a array pointer from a function as that piece of memory is concidered unsafe (unless that array has been defined in the object and is deleted in the objects deconstructor)...

Some examples:

#include <iostream>
#include <string>
using namespace std;

class HTMLpage {
public:
string out(string)
};

string HTMLpage::eek:ut(string str) {
str=&quot;<html>\n<body>\n&quot;+str+&quot;\n</body>\n</html>\n&quot;;
return str;
};

void main() {
HTMLpage pg;

cout << pg.out(&quot;Hello&quot;);
}

Is it possible to return a string object as in the above example and be safe or is a string object excatly the same as a char array? Or for that matter is it possible to return any type of user made object from a function? Or would I be better off defining in the object a string variable member and just using that instead ... eg:

class HTMLpage {
public:
void out(string);
string src;
};

void HTMLpage::eek:ut(string str) {
src=&quot;<html>\n<body>\n&quot;+str+&quot;\n</body>\n</html>\n&quot;;
};

I've been spoilt with higher level languages for too long :S
 
Hi Flappy, it's often much easier to use references rather than returning values or using pointers. It's a simpler syntax and there's no invokation of a copy constructor to worry about.

Basically, a reference is like an &quot;alias&quot; to the original object. You define a reference by placing an ampersand (&) after the typename. This function takes a reference to an int:
[tt]
void DoSomethingToInt(int& i)
{
i = 27;
}[/tt]

To call this function there's no need for special syntax - just call it like any other function:[tt]

void main(void)
{
int myInt = 84;

DoSomethingToInt(myInt);

printf(&quot;myInt = %d&quot;,myInt);
}[/tt]

If you compile this you'll notice the print out value is 27 - this is because [tt]DoSomethingToInt()[/tt] took a &quot;reference&quot; (or alias) to myInt and changed the original!
tellis.gif

programmer (prog'ram'er), n A hot-headed, anorak wearing, pimple-faced computer geek.
 
Hi qednick,

Thanks for the reply, I've been using Perl for around 5 years now and I have concidered the way that you have shown me there cause I've done alot of that stuff in Perl. But I like the idea of encapulation of having local variables and just returning the function/methods output once its finished and not have to worry about it anymore, cause once my program starts getting big the idea of having alot of global variables etc just makes it hard to keep track of everything. So would it be bad to use the first example that I gave in the beginning? Also whats that about a copy constructor that you are saying there?

Thanks :)
 
Hi Flappy, hmmmm... ok, first things first: the whole object of OOP programming is to eliminate global variables and the like. If you can write an entire program without a single global variable in it then you've done a good job. Consider the OOP model: it's all based on reusable code (or classes). You create a class with member variables and functions. That class is responsible for its own internal upkeep. Some of the internals are public others are private/protected. Classes exchange information by using messaging (see my FAQ in the Visual C++ forum regarding Windows messaging) rather than global variables.
If you stick some global variables (and/or global functions) in your program, it becomes harder to transport your classes into new projects that may reuse that tried-and-tested code you wrote earlier.
For example, if you were to write a program that mimmicked a car manufacturer, you may consider the main() function as the chassis and have a class for the engine, a class for the transmission and so on. In the engine class you would have things like pistons, crankshaft, etc which are declared as private members. You would also have things like the oil level and water temperature which would have public access. This is because you don't want your transmission to be screwing around with the pistons or other private internals but you would like other classes to have public access to the oil level and water temp. (eg. a temp. gauge class).
You should &quot;factor&quot; your classes out while you're bashing out your idea for the program. This means stripping everything down to the bare minimums and sorting them into classes and determining how everything will fit together.
This may seem like a chore but it will make your programming life SO MUCH easier when it comes to actually writing the code. It also makes it easier to put a large project together when there's more than one person involved in the coding.

There will be times when you need to use single return values and times when you need to use references/pointers. If you're not familiar with pointers see my FAQ on the subject in this forum). I would design a function to return a value if I intend to use that function within other parameters, eg:

[tt]SomeFunction( GetValue() );[/tt]

Like the above example and similar circumstances. I'll use references when I need to get a couple of values back from a function or if I'm passing in/out a large structure such as a class I've written.
Returning values is fine - just make sure that your code is working as expected (make no assumptions). If your strings are returning fine and as expected then that's great!
If I was going to pass/return an array to a function I would use a pointer to the array.

A copy constructor is a special kind of constructor used for making copies of an object. An old programming rule is that if you have any one of these in your class:

1. Assignment operator
2. Destructor
3. Copy Constructor

Then you should have all three! The reason for a copy constructor is actually quite simple: if you create a class with a few member variables and then pass an object of that class to another function:[tt]

class MyData
{
....
};

MyData myObject;
SomethingFunction( myObject );[/tt]

The compiler doesn't simply pass in myObject, it creates a copy of it! This copy is not always desirable because you may have allocated memory for some of members or whatever. There's no guarantees that the memory is going to be destructed properly once SomethingFunction() completes and the local copy of myObject parameter goes out of scope! This is a prime source of memory leaks for many new programmers!!
The best thing to do is to create an overloaded assignment operator for your class and then use that in the copy constructor.

I don't want to babble on too much for fear of confusing you. Just give me a shout if you get stuck or have any other queries. :)
tellis.gif

programmer (prog'ram'er), n A hot-headed, anorak wearing, pimple-faced computer geek.
 
It's safe to return a string object. A string cleans up after itself (by calling a destructor), and a char* doesn't.

Likewise, if you want to return any array, you should return a vector. It also cleans up after itself, unlike C-style arrays (e.g. in*).

It's safe to return objects of user-defined types as long as you've defined those types corrctly (i.e. copy constructor and destructor working; and yeah, assignment operator wouldn't hurt).
 
Hey chipper - how's it going? Noticed you were also having some minor troubles in the C forum regarding your C code too (looked remarkably like good old fashioned C code to me!).
Yeah Flapper, vectors are a good substitute for arrays. As you probably know with your Perl coding - there's usually more than one way to skin a cat.
I also wondered what compiler and platform you're using?
tellis.gif

programmer (prog'ram'er), n A hot-headed, anorak wearing, pimple-faced computer geek.
 
Heh heh. I think he had more of a problem with the fact that I described an algorithm in English instead of writing the actual code. When you just write code, the other guy doesn't learn anything except Ctrl-C and Ctrl-V.
 
Great! Thanks for the feedback thats guys much apprecated!!!!! I just want to make sure my programs are running correctly and nothing suspicious happening behind the scenes. Thanks for the little tut on OO qednick hehe I've also been programming in javascript and java for a fair few years too so I completely understand OOP, it's just C/C++'s little quirks that I wasnt sure about but you guys have cleared it up for me! Now I feel I can move along and know what I'm doing now.

BTW chipperz I'm using Visual C++ but trying to stick to the standard libraries so my code will be portable.
 
(1) Dear gednick, thanks for incredibly helpful stuff on OOP. I like the car analogy. I have a question though: when I read OOP books they always use shapes and points as their example, so they define a point, with coordinates, and then they make methods to move the point, and then they tell me this is great because I can now define a square as 4 points, and my square will automatically be moveable, because it inherits the move method of its 4 points. This gives me the heeby jeebies, because a big bit of me screams that a square only needs 4 bits of data, not the 8 I now have, and moving it by 4 separate calls to 4 highly unspecialised routines strikes me as very inefficient. I KNOW I can move a square a whole lot easier... So I get more and more worried that I'm going to end up with one of those programs that works, in the sense that it's easy to maintain, and does (eventually) do the job, but which chunters away at its hard drive for 5 minutes every time I ask it to do the simplest operation (you must know the feeling). I know it's very untrendy to write likt this in an OOP world, but please can you put me out of my misery and point me towards somewhere where I can find out how to overcome this sort of thing... a sort of OOP therapy page for fans of structured programming who just can't make that final leap?

(2) Dear chipperMDW. Keep describing in English, there's nothing wrong with it. Your explanations are really helpful, and I also find it much easier to understand than a 100-line chunk of someone else's half-commented code and a smiley. Also look at it this way: the person you're helping might be a student with homework difficulties, whatever the forum instructions. And someone once told me if I do their assignments without their having to do any work, is that good when they later get paid to write the safety system of a nuclear power station??
 
Chipper: yes I kind of figured that one - and that guy had german in his post! LOL

Flappy: Sorry about the sucking eggs thing! [bugeyed]

Lionel: A couple of things - first, if you see that rvijay17 guy again who made the post on the linked lists, can you tell him I wrote an FAQ for him an he can find it in any of the C++ forums (I struck the C forum off my list).
Secondly, I don't know exactly what your level of expertise in C++/OOP is (I don't want to teach you to suck eggs too!) - all I can tell you is that I recall a long time ago I had been programming in C for quite some time. When the idea of C++ came about and I was thinking &quot;what's all this about?&quot; it actually took me on the order of about 2 weeks to fully realize the potential of OOP. Now I've been using C++ for the last few years there's no way in hell I would want to go back to using plain old C.
Lionel, give me your e-mail and I'll send you an article on making the transition from C to C++. It tries not to confuse but gives some good analogies. [idea]
tellis.gif

programmer (prog'ram'er), n A hot-headed, anorak wearing, pimple-faced computer geek.
 
BTW, love the power station thing Lionel
tellis.gif

programmer (prog'ram'er), n A hot-headed, anorak wearing, pimple-faced computer geek.
 
Lionel, it's important to learn to strike a balance between modularity and practicality; representing a square as 4 points is a nice example for beginners, but without some compelling reason to do otherwise, most people would just represent a square as an upper-left corner (or maybe a center point) and a side length. There's a limit to how much you can divide something into parts before doing so stops being useful.

For example, to represent a cat, you'd divide it into pieces that are useful to you. In most cases, it would be tedious, unrewarding, and horribly inefficient to represent a cat as a collection of organs, each of which is a collection of tissues, each of which is a collection of cells, each of which is a collection of organelles, each of which is a collection of atoms... The &quot;best&quot; representation would depend on what you want to do with it. In a game, you'd probably represent a cat as a collection of statistics, such as health, position, speed, power, etc. In an environmental program, you'd have some representation of the cat's behavior and age and similar information.
 
If I were to define some classes for shapes (such as squares, etc) I would first define a base class called &quot;Shape&quot;. The base class would have a container (such as a vector, etc) of points plus any relevant drawing, rotating functions, area, enlargement and reduction, etc. That way, you can define any shape class (eg. Triangle, Polygon, etc.) from the base &quot;Shape&quot; class with any number of points.
Now if there is a Move() function in the base &quot;Shape&quot; class, that base function should move all the points in the vector - regardless of how many points are in there! So it actually shouldn't make a difference whether you are moving a triangle or a square, the base Move() function should be able to handle it.
So you can see it would be inefficient to define a set number of points in the derived classes. Because all shapes can be defined using a series of points, that series (vector) of points should be defined in the base class instead.
Because of this, I think your OOP book has taken an incorrect approach. I have developed a CFCPoint template class (so we can use double-precision coordinates if required) which has member functions to calculate precise angles and distances. Now this is where your book gets a bit skewed (like you pointed out) - the Shape class should not inherit from the Point class because a Shape is not a kind of point. Instead, it should simply contain a series of points because a Shape is made out of a series of points.
It is the Triangle, Square, etc. classes that should inherit from Shape because they are shapes! These derived classes will then have the series of points available to them from the base Shape class. Does this make sense?
tellis.gif

programmer (prog'ram'er), n A hot-headed, anorak wearing, pimple-faced computer geek.
 
Thanks all for very helpful replies.
Gednick, I see the point about a &quot;shape&quot; class and I'd love to have a look at the article. If you have time etc. to send it you can reach me at lionel_m_hill@hotmail.com. I've got very very little expertise at OOP, with a background in pascal (embarassment to admit it nowadays..) and a liking for assembler. Although of course pascal did the OOP thing before it disappeared, I found Borland's explanations a bit hard to follow. Now I tend to maltreat C++ and use it very much like I used to use pascal. So that's my level. Incidentally because I like assembler I also like to understand what the compiler does with my code, and OOP is quite a big jump from that point of view.

If anyone in &quot;C&quot; asks about linked lists, esp rvijay, I'll point them at the FAQs.

And special thanks to the person who gave me a big star for my question! I'm flattered but undeserving...
 
&quot;a liking for assembler&quot;

I could never get my head around assembler! [hammer]
I've sent you an e-mail lionel. :)
tellis.gif

programmer (prog'ram'er), n A hot-headed, anorak wearing, pimple-faced computer geek.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top