Beginner questions

P

Pelle Beckman

Hi all,

I have a few newbie questions:

In function declaration what does a 'const' mean
inside the parameter list ? That it won't modify the value?

void MemberFunction(const int x);


What does 'const' before a function dec. mean?

const void MemberFunction(int x);

The same as 'static'?


My pointer skills aren't perfect, so what is
the differece between these functions?

void MyFunction(int& x);
void MyFunction(int* x);


Why can't ctors and dtors be "totally virtual"?

class MyClass {
virtual MyClass() = 0;
virtual ~MyClass() = 0;
};

How do I specify that one class should inherit
both public AND protected members from a base class?
Using 'friend'?

And what's so very good about iterators compared
to an ordinary for-statement?
As in:

for(vector<int>::iterator etc ... )
vs.
for(int i = 0; i < myvector.size() etc ...)


Thanks.

-- Pelle
 
J

Jerry Coffin

Pelle said:
Hi all,

I have a few newbie questions:

In function declaration what does a 'const' mean
inside the parameter list ? That it won't modify the value?

void MemberFunction(const int x);

Yes, but in this example it's meaningless -- 'const' on a parameter is
meaningful wrt a pointer or reference:

void MemberFunction(const int &x);
void MemberFunction(const int *x);

in these cases it isn't really the parameter itself that the function
promises it won't modify, but the object that points at/refers to.

Since the parameter (unless it's a reference) is always a copy of some
value, changing it doesn't really mean much.
What does 'const' before a function dec. mean?

const void MemberFunction(int x);

It means that what's being returned is a const (whatever). Again, this
example has a minor problem -- since a function with a void return type
doesn't return anything, you can can't declare that nothing that's
being returned as const.

Something like:

const int MemberFunction(int x);

does make some sense, though a const on the return is more common when
you're returning something like a full-fledged object.
The same as 'static'?

No, not even similar. The const affects the type of object being
returned. In the same place, static would affect the type of the
function itself -- assuming (as the name implies) that this was a
member function, it would make it a static member function. A static
member function is almost comppletely different from a normal member
function because it's not associated with a particular instance of the
object.
My pointer skills aren't perfect, so what is
the differece between these functions?

void MyFunction(int& x);
void MyFunction(int* x);

The first receives a parameter by reference, while the second recieves
a pointer. The two often accomplish similar things, but a reference
always refers to the same object for its entire lifetime, while a
pointer can be changed so it points at different objects at different
times (or to nothing at all, if you so desire).
Why can't ctors and dtors be "totally virtual"?

class MyClass {
virtual MyClass() = 0;
virtual ~MyClass() = 0;
};

That's "pure virtual", in case you care. In any case, a dtor _can_ be
pure virtual if you want. A ctor can't be virtual -- or is always
virtual, depending a bit on your viewpoint, but in any case, you can't
specify it as virtual at all, and without that, pure virtual is
completely out of the picture.
How do I specify that one class should inherit
both public AND protected members from a base class?
Using 'friend'?

Anytime you do inheritance, you derive both public and protected
members from the base class.
And what's so very good about iterators compared
to an ordinary for-statement?
As in:

for(vector<int>::iterator etc ... )
vs.
for(int i = 0; i < myvector.size() etc ...)

In this particular case, the iterator provides little real advantage --
the primary reason for using iterators is to pass them to algorithms.
The reason algorithms use them is to abtract iteration, so the
algorithm can use the same code to work with different kinds of
containers. Getting from one node in a linked list to the next is a lot
different from getting from one element in an array to the next, but
iterators allow you to write your code the same way to do either (or to
work with various other containers as well). At least in theory, this
makes it easier to substitute one container for another, though there
are some limitations on this -- the iterator gives a common syntax, but
doesn't change the fundamentals, so an iterator won't (for example)
give you random access to data that's arranged to only allow serial
access.
 
P

Pelle Beckman

Jerry Coffin skrev:
Yes, but in this example it's meaningless -- 'const' on a parameter is
meaningful wrt a pointer or reference:

void MemberFunction(const int &x);
void MemberFunction(const int *x);

in these cases it isn't really the parameter itself that the function
promises it won't modify, but the object that points at/refers to.

Since the parameter (unless it's a reference) is always a copy of some
value, changing it doesn't really mean much.




It means that what's being returned is a const (whatever). Again, this
example has a minor problem -- since a function with a void return type
doesn't return anything, you can can't declare that nothing that's
being returned as const.

Something like:

const int MemberFunction(int x);

does make some sense, though a const on the return is more common when
you're returning something like a full-fledged object.




No, not even similar. The const affects the type of object being
returned. In the same place, static would affect the type of the
function itself -- assuming (as the name implies) that this was a
member function, it would make it a static member function. A static
member function is almost comppletely different from a normal member
function because it's not associated with a particular instance of the
object.




The first receives a parameter by reference, while the second recieves
a pointer. The two often accomplish similar things, but a reference
always refers to the same object for its entire lifetime, while a
pointer can be changed so it points at different objects at different
times (or to nothing at all, if you so desire).




That's "pure virtual", in case you care. In any case, a dtor _can_ be
pure virtual if you want. A ctor can't be virtual -- or is always
virtual, depending a bit on your viewpoint, but in any case, you can't
specify it as virtual at all, and without that, pure virtual is
completely out of the picture.




Anytime you do inheritance, you derive both public and protected
members from the base class.




In this particular case, the iterator provides little real advantage --
the primary reason for using iterators is to pass them to algorithms.
The reason algorithms use them is to abtract iteration, so the
algorithm can use the same code to work with different kinds of
containers. Getting from one node in a linked list to the next is a lot
different from getting from one element in an array to the next, but
iterators allow you to write your code the same way to do either (or to
work with various other containers as well). At least in theory, this
makes it easier to substitute one container for another, though there
are some limitations on this -- the iterator gives a common syntax, but
doesn't change the fundamentals, so an iterator won't (for example)
give you random access to data that's arranged to only allow serial
access.

--
Later,
Jerry.

The universe is a figment of its own imagination.

Thanks Jerry.

Followups:

Why would I want to return a const object?
(as in "const MyClass MyFunction()")
are there any good examples for this use?

What is the advantage of telling the
compiler that a function promises not
to modify the value (as in "void Method(const int* x)") ?

If there is a value I can't modify - shouldn't I just
make sure it doesn't when I write the darn thing?
 
K

Karl Heinz Buchegger

Pelle said:
Hi all,

I have a few newbie questions:

In function declaration what does a 'const' mean
inside the parameter list ? That it won't modify the value?

void MemberFunction(const int x);

It tells the compiler, that this function will not modify x.
In your particular example, this is useless, because it really
doesn't matter to anybody,if this functions alters x or not.

But consider ouy have a function, which takes a reference:

void foo( int& a );

Now you call that function:
int main()
{
int x = 5;
foo( x );
}

And here comes the question: Does the function foo() alter
x, or does it not?. Since foo gets x passed by reference foo()
can do that. In this case you have no other choice then to assume
that it does.

Now if the function wants to signal to the caller: Don't worry, I will
not touch what you have given me, it can do so:

void foo( const int& a );

Now the function declaration clearly says: I will take that int by reference,
but I will not alter it inside the function.
What does 'const' before a function dec. mean?

const void MemberFunction(int x);

Something like 'const void' does not exist.

const int MemberFunction( int x );

That const is part of the return type: It says that this function
returns an int, and that this int is constant (cannot be altered
by the caller). Again: This is pretty useless with an int, but

const char* Fnct();

says that the Function returns a pointer. A pointer to characters. And
those characters are constant.
The same as 'static'?

No. static tells us something about the function itself. The const
is simply part of the return type.
My pointer skills aren't perfect, so what is
the differece between these functions?

void MyFunction(int& x);
void MyFunction(int* x);

The first one gets a reference, while the second one gets a pointer.
In this case, you can view a reference as some sort of 'hidden pointer'.
A pointer which exists but isn't usable by you, the compiler takes care of it.
You want to do that to get a nicer syntax inside the function when accessing
x.
Why can't ctors and dtors be "totally virtual"?

Well. A dtor can. And in case of polymorphism it often has
to be.
As for a ctor: How would you create an object of a class, when
you don't now the class type during compile time?
class MyClass {
virtual MyClass() = 0;
virtual ~MyClass() = 0;
};

How do I specify that one class should inherit
both public AND protected members from a base class?
Using 'friend'?

A class inherits always *all* members from its base class.
The only question is: can a derived class access those members
or can it not.
And what's so very good about iterators compared
to an ordinary for-statement?
As in:

for(vector<int>::iterator etc ... )
vs.
for(int i = 0; i < myvector.size() etc ...)

The iterators work on all stl containers the same way
(nearly, there are small exceptions, but in the above
case, it would not matter, if the container is a vector,
a map, a deque, a multimap, ...). Thus you can chance the
type of container without having to change your source code.
Just in case your choosen container turns out to behave poorly
and you want to try a different one.
Also: This opens the door for general algorithms. Those algorithms
work with iterators and it doesn't matter to which container this
iterators belong. The algorithm is always the same.
 
J

John Carson

Jerry Coffin said:
Yes, but in this example it's meaningless.

Not quite. With or without const, x won't be modified in the scope from
which the function call was made, but const makes a difference in that
attempts to modify x inside the function will give compiler errors. Without
const you can modify x to only local effect, just as if you had declared x
in the body of the function.
 
A

Andre Caldas

Why would I want to return a const object?
(as in "const MyClass MyFunction()")
are there any good examples for this use?

Because you don't want people messing around with your object's internal
structure. When you pass a reference to such a variable, you should pass
a "reference to a const".

What is the advantage of telling the
compiler that a function promises not
to modify the value (as in "void Method(const int* x)") ?

The compiler will make sure you don't change the value pointed to x. For
example:

void F (int* x);
void G (int& x);
void H (int x);
void I (const int* x);

void Method (const int* x)
{
F(*x); // Error!
G(x); // Error!
H(x); // OK
I(x); // OK
}

If there is a value I can't modify - shouldn't I just
make sure it doesn't when I write the darn thing?

To state that your program has no errors, you need to prove
mathematicaly that it does what you expect. It's easier to prove things
if your assumptions are stronger.

For example, if you use global variables, inside function A, you cannot
assume the global values will not change when you call some supposedly
unrelated function B from inside A. Now, when you are writing the
function A, you cannot reason "locally" about it's behaviour, because it
will depend on the internals of B.

The same is true for references. When you pass a reference to function A
but you don't expect A to change the value pointed by the reference what
do you do? Check the source for A to see if it does infact do something
you didn't want? Or you just let the compiler (and the good-design) help
you on that?

Supposing you do check A's source, will you check every function A calls
and forwards your reference? It's very easy for the compiler to do this
for you.

Try changing your programs to use "const" whenever possible. You will
have so much trouble doing this... this does not mean "const" is bad.
This means your code does not do what you think it does - and the
compiler will *prove* it to you.

Andre Caldas.
 
C

codigo

Pelle Beckman said:
Jerry Coffin skrev:

Thanks Jerry.

Followups:

Why would I want to return a const object?
(as in "const MyClass MyFunction()")
are there any good examples for this use?

When you see the keyword const you should think "contract". The const
keyword in this context is better understood from the perspective that there
is both the creator of the class and the user of the class (creator and
client programmer). It helps the creator and user of the class encapsulate
the class.
What is the advantage of telling the
compiler that a function promises not
to modify the value (as in "void Method(const int* x)") ?

If there is a value I can't modify - shouldn't I just
make sure it doesn't when I write the darn thing?

What if you decide to reuse your class six months from now? How are you
going to remember which method or overridden method has parameters that
shouldn't be modified? Why rely on memory when dealing with a boat-load of
classes and methods when you can write a rule, or contract, that lets you
use the compiler to enforce the constant rules.

How can you guarentee that a given object isn't improperly modified by
another programmer?

Lets suppose that you've decided to include another programmer's class in
your project, how do you know that a given method's parameter or return
should be constant?
 
R

Rolf Magnus

John said:
Not quite. With or without const, x won't be modified in the scope from
which the function call was made, but const makes a difference in that
attempts to modify x inside the function will give compiler errors.

Yes, but the above is a function declaration only, i.e. it specifies the
interface. But the const is not part of the interface, it doesn't change
anything for the caller.
Without const you can modify x to only local effect, just as if you had
declared x in the body of the function.

You can declare it const in the body, too.
 
R

Rolf Magnus

Karl said:
Something like 'const void' does not exist.

I'm actually wondering about that. Would it still be legal? After all, you
can declare a pointer to const void.
As for a ctor: How would you create an object of a class, when
you don't now the class type during compile time?

To put it in other words: A virtual function call is dynamically (i.e. at
runtime) dispatched to the actual class of the object it's called for, so
it needs an object that already exists. But a constructor is part of the
creation of an object. How would the system know which class you want to be
instantiated unless you explicitly specify it? It's a hen/egg problem. The
object doesn't exist yet, so you cannot determine its type to choose the
constructor that you want to use for creating it. You have to specify the
type explicitly, and therefore, a virtual constructor doesn't make sense.
A class inherits always *all* members from its base class.

Constructors are not inherited.
The only question is: can a derived class access those members
or can it not.

If it can't, can that still be considered to be inheritance?
 
G

Gary Labowitz

This is actually a reply to all of you.
I teach C++ and these looked like pretty good take-home exam questions to
me. Anyway, we have no way of telling if this was an exam or not.
 
P

Pelle Beckman

Gary Labowitz skrev:
This is actually a reply to all of you.
I teach C++ and these looked like pretty good take-home exam questions to
me. Anyway, we have no way of telling if this was an exam or not.

Gary,

First, these questions are not from a McExam - I've been out
of school for many years now and I've never attended
a programmers course.

Second, It sounds like this is a problem to you.
These guys and gals here are actually learning both
myself and themselves a few things by having me asking them.

Have you ever taught the wonders of asking questions?

-- Pelle
 
J

John Carson

Rolf Magnus said:
You can declare it const in the body, too.

Of course. My point (not expressed well) is that you can use function
arguments as "scratch" variables, notwithstanding that the more common
practice is to declare "scratch" variables in the body of the function.
 
G

Gary Labowitz

Pelle Beckman said:
Gary Labowitz skrev:

Gary,

First, these questions are not from a McExam - I've been out
of school for many years now and I've never attended
a programmers course.

Second, It sounds like this is a problem to you.
These guys and gals here are actually learning both
myself and themselves a few things by having me asking them.

Have you ever taught the wonders of asking questions?

Dont' get excited. I might use some of those questions in an exam some day.
I think it's not just a problem for me. Most of the posters here shy away
from answering what look like homework questions for all kind of reasons.
There is no animosity toward the questioner, we just don't want a student
getting a grade for someone else's work.
It is, of course, difficult to know perfectly which are and which aren't
homework questions, although some appear obvious.
Ah, it's an imperfect world. The usual way of handling the questions is to
ask the poster to show code that they are having trouble with and help him
to program through any problems with that. It at least shows some effort on
the part of the poster to try doing the work himself.

Solution? There is no perfect one. As I said, "we have no way of telling if
this was an exam or not."
 
A

Andre Caldas

Rolf said:
I'm actually wondering about that. Would it still be legal? After all, you
can declare a pointer to const void.

"const void*" is not meaningless! It says that it is a pointer to
something that cannot be changed.

Example:

const char* p = "hello, Rolf!";
void* a = p; // Is this OK? (warning: I don't really know)

Andre Caldas.
 
R

Rolf Magnus

Andre said:
"const void*" is not meaningless!

I didn't say that. I was just wondering about the sentence: "Something like
'const void' does not exist.". Since a pointer to const void does exist, it
seems logical that const void does exist too, though probably not really
meaningful.
It says that it is a pointer to something that cannot be changed.

However, it cannot be changed anyway through a pointer to void. But for
const correct programming, it could be useful to have a const void*.
 
R

Raymond Martineau

"const void*" is not meaningless! It says that it is a pointer to
something that cannot be changed.

Example:

const char* p = "hello, Rolf!";
void* a = p; // Is this OK? (warning: I don't really know)

In this case, it isn't okay since the automatic conversion loses the const
qualifier. If you add const or remove it with const_cast (which is what
you intended), it is perfectly fine on a standard compiler.
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top