Which is the better way to define methods?

B

Blue Ocean

My c++ text tells me that I should define methods this way:

class Stack
{
int method(double t);
Stack(int s);
...
}

int Stack::method(double t)
{
/* behavior */
}

but my experience with Java tells me that this way is better:

class Stack
{
int method(double t)
{
/* behavior */
}

Stack(int s)
{
/* behavior */
}
}

Which way do you use? Should I use the first or the second? I'd
rather develop good habits as I teach myself C++ rather than have to
go back and fix bad ones later. Thank you in advance for the help.
 
J

John Harrison

My c++ text tells me that I should define methods this way:

class Stack
{
int method(double t);
Stack(int s);
...
}

int Stack::method(double t)
{
/* behavior */
}

but my experience with Java tells me that this way is better:

class Stack
{
int method(double t)
{
/* behavior */
}

Stack(int s)
{
/* behavior */
}
}

Which way do you use? Should I use the first or the second? I'd
rather develop good habits as I teach myself C++ rather than have to
go back and fix bad ones later. Thank you in advance for the help.

If you use the second method then you are putting all you code into header
files. Some people don't like that, either because they think the code
should be private, or they worry about the extra compilation time from
large header files.

But really it's not a big issue. With more and more people writing
template code (where you have to put the code in the header file anyway)
your method is becoming much more common.

john
 
E

E. Robert Tisdale

Something said:
My C++ text tells me that

Which C++ text are you reading?
I should define methods this way:

class Stack { public:
int method(double t);
Stack(int s);
...
};
inline
int Stack::method(double t) {
/* behavior */
}

but my experience with Java tells me that this way is better:

class Stack { public:
int method(double t) {
/* behavior */
}

Stack(int s) {
/* behavior */
}
};

Which way do you use? Should I use the first or the second?
I'd rather develop good habits as I teach myself C++
rather than have to go back and fix bad ones later.

You need to *unlearn* your Java habits.
If you define constructors, functions or operators
within the class definition, they are inline functions.
You can move the function definition out of the class definition
but you must qualify it with the 'inline' keyword
or move the definition into a separate *implementation* source file
where it will be compiled exactly *once*!
 
J

JKop

It's purely cosmetic.

I myself would prefer:

// Poo.hpp (HEADER FILE)

class Poo
{
private:

double data;

public:

void Increase5Percent();
void Increase20Percent();
};

inline void Poo::Increase5Percent()
{
double *= 1.05;
}

inline void Poo::Increase20Percent();
{
double *= 1.2;
}


OVER:

// Poo.hpp (HEADER FILE)

class Poo
{
private:

double data;

public:

void Poo::Increase5Percent()
{
double *= 1.05;
}

void Poo::Increase20Percent()
{
double *= 1.2;
}
};


Consider if you had 23 inline functions, it's nice to still have a nice
compact class declaration.


-JKop
 
R

red floyd

Blue said:
My c++ text tells me that I should define methods this way:

class Stack
{
int method(double t);
Stack(int s);
...
}

int Stack::method(double t)
{
/* behavior */
}

but my experience with Java tells me that this way is better:

class Stack
{
int method(double t)
{
/* behavior */
}

Stack(int s)
{
/* behavior */
}
}

Which way do you use? Should I use the first or the second? I'd
rather develop good habits as I teach myself C++ rather than have to
go back and fix bad ones later. Thank you in advance for the help.


The first, with separate files for the class definition and
implementation. If I decide that I want to change how
Stack::method(double) works, I don't have to recompile everybody who
*uses* Stack, just Stack itself and then relink.
 
B

Blue Ocean

E. Robert Tisdale said:
Which C++ text are you reading?

_The C++ Programming Language_ by Bjarne Stroustrup.

You need to *unlearn* your Java habits.
If you define constructors, functions or operators
within the class definition, they are inline functions.
You can move the function definition out of the class definition
but you must qualify it with the 'inline' keyword
or move the definition into a separate *implementation* source file
where it will be compiled exactly *once*!

So . . . I wasn't thinking at all about inline functions. If a method
is defined inside the class definition, that's what happens? So, tell
me if this is right (for normal, non-inlined methods:

========================================
/* file.h */
class Stack
{
private:
int somethingoranother;

public:
Stack();
~Stack();
int foo(double bar);
}

/* file.cpp */
int Stack::foo(double bar)
{
//Behavior
}

Stack::Stack()
{
//Behavior
}
========================================

If that is right, let me extend the question a little. Should I
declare private methods in the .h file? Or should I declare them in
the .c file?
 
E

E. Robert Tisdale

Blue said:
E. Robert Tisdale wrote:
[snip]
You need to *unlearn* your Java habits.
If you define constructors, functions or operators
within the class definition, they are inline functions.
You can move the function definition out of the class definition
but you must qualify it with the 'inline' keyword
or move the definition into a separate *implementation* source file
where it will be compiled exactly *once*!

So . . . I wasn't thinking at all about inline functions.
If a method is defined inside the class definition, that's what happens?
So, tell me if this is right (for normal, non-inlined methods:


========================================
#ifndef guard_file_h
#define guard_file_h
// file.h

class Stack {
private:
int somethingoranother;

public:
Stack(void);
~Stack(void);
int foo(double bar);
};
#endif// guard_file_h
// file.cpp #include "file.h"

int Stack::foo(double bar) {
// Behavior
}

Stack::Stack(void) {
// Behavior
}
========================================

If that is right, let me extend the question a little.
Should I declare private methods in the .h file?
Or should I declare them in the .c file?

You must *declare* them in the class definition.
You may *define* them in the header file as *inline* functions.
 
I

Ivan Vecerina

Blue Ocean said:
If that is right, let me extend the question a little. Should I
declare private methods in the .h file? Or should I declare them in
the .c file?

In Java, you'll often find private methods, and especially static private
methods, which in C++ are best implemented as non-member utility functions
within the .cpp file.

C and C++ are abit archaic in that they use this subdivision between a
header and a source file, which is an artefact from the way the compilers
work. Java avoids this problem because the equivalent of a header is
generated by the compiler automatically, in a binary form.
The only benefit of headers is that they give you more control regarding
what will be seen by a user of a library. But it is also a burden...

A rule of thumb in C/C++ is that you keep as little information as possible
outside of the headers.
You therefore try to only put in a .h file what has to be accessible to the
users -- the exception being private members of a class, which are not used
from the outside, but need to be declared within a class definition ( class
A { /*here*/ }; ).
Sometimes, putting less information in a header requires specific
workarounds, such as the "pimpl" idiom or the use of abstract base classes.

hth,
Ivan
 
T

Thomas Matthews

Blue said:
My c++ text tells me that I should define methods this way:

class Stack
{
int method(double t);
Stack(int s);
...
}
I prefer:
struct Stack
{
int method(double t);
Stack(int i);
};

or

class Stack
{
public:
// Constructors:
Stack(int s);

// Methods in alphabetical order
int method(double t) const;
};

int Stack::method(double t)
{
/* behavior */
}

but my experience with Java tells me that this way is better:

My experience with C++ tells me that a class's default
access is private and a struct is public.

class Stack
{
int method(double t)
{
/* behavior */
}

Stack(int s)
{
/* behavior */
}
}

Which way do you use? Should I use the first or the second? I'd
rather develop good habits as I teach myself C++ rather than have to
go back and fix bad ones later. Thank you in advance for the help.

I prefer to list all the declarations of members and methods in
the class and their implementations outside of the class.

For simple functions, I declare them as inline in the header file
(the file containing the class declaration). For more complex
methods, I place them into a source / .cpp / translation unit.

With bigger projects, changing the content of a method residing
in a separate translation unit reduces the need to recompile all
other files that depend on the header file. Templates are another
situation though. :-(


--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book
 
P

puppet_sock

JKop said:
It's purely cosmetic.
[about putting function implementation in the class def or not]

It's largely cosmetic, but not purely.

- It can increase compile times on many platforms.
- It can change dependancies requiring more files to be recompiled.
- It exposes implementation details in header files un-necessarily.
Socks
 
P

Phlip

JKop said:
It's purely cosmetic.
[about putting function implementation in the class def or not]

It's largely cosmetic, but not purely.

- It can increase compile times on many platforms.
- It can change dependancies requiring more files to be recompiled.
- It exposes implementation details in header files un-necessarily.

One might first question the practice of instantly putting every class, as
you create it, into a new .h file named after it.

Suppose method A::Q needs new class B. Write it as close to Q as possible.
Migrate B to a .h file if and only if someone else needs it.

If nobody needs it without A, migrate it to A's .h file.
 
G

Gary Labowitz

Ivan Vecerina said:
C and C++ are abit archaic in that they use this subdivision between a
header and a source file, which is an artefact from the way the compilers
work. Java avoids this problem because the equivalent of a header is
generated by the compiler automatically, in a binary form.

A side note: Java doesn't have the equivalent of a header, generated by the
compiler or otherwise. It loads and uses the class file for referenced
classes to resolve the static references at compile time. You may have
thought Java was "generating" the class file because it automatically
compiles it when needed if it can't find a precompiled class file, IF it can
find the source file with the same name. [This may sound a little confusing,
but I can't go into all the details on a C++ group -- see
comp.lang.java.programmer for further information if needed.]
 
I

Ivan Vecerina

Gary Labowitz said:
message news:[email protected]...

A side note: Java doesn't have the equivalent of a header, generated by the
compiler or otherwise. It loads and uses the class file for referenced
classes to resolve the static references at compile time. You may have
thought Java was "generating" the class file because it automatically
compiles it when needed if it can't find a precompiled class file, IF it can
find the source file with the same name.
I'm aware of how Java functions. For the purpose of this discussion, the
compiled class file is for me the "binary form" equivalent of a C/C++
header,
in that this is where the compiler looks up information it needs for static
linking.

Some compilers already leverage 'precompiled headers', although they are
functionally limited (i.e. typically required to be the first header
included).

The (rarely available) implementation of template export also requires
something
similar to a header in compiled form.

Maybe someday, it will be common for C++ implementations to at least store
pre-compiled binary versions of headers. Or maybe some form of "class
export"
could make the 'pimpl' idiom be history, by avoiding contamination
with indirect header dependencies...


.... just thinkin' aloud ...
Ivan
 
J

jeffc

Blue Ocean said:
My c++ text tells me that I should define methods this way:

class Stack
{
int method(double t);
Stack(int s);
...
}

int Stack::method(double t)
{
/* behavior */
}

but my experience with Java tells me that this way is better:

class Stack
{
int method(double t)
{
/* behavior */
}

Stack(int s)
{
/* behavior */
}
}

Which way do you use? Should I use the first or the second?

Sorry, but your question makes no sense. I could try to speculate as to
what you mean, but you're better off proofreading that and taking another
shot. You defined a constructor in the second example, but not the first.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,054
Latest member
LucyCarper

Latest Threads

Top