473,387 Members | 1,495 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Help a poor FORTRAN programmer with member functions?


Just a bit of background: I'm one of a group of FORTRAN programmers, looking
to switch to C++. We are trying to write a few simple examples to
demonstrate the power of the language to our manager, so he will send us all
on a conversion course.

One of many reasons is that our code is littered with examples of:

SUBROUTINE PRINT_ITEM(ITEM, ITEM_TYPE)
IF (ITEM_TYPE .EQ. SQUARE) THEN
CALL PRINT_SQUARE(ITEM)
ELSEIF (ITEM_TYPE .EQ. CIRCLE) THEN
CALL PRINT_CIRCLE(ITEM)
ELSEIF ...
(lots more item types)
ENDIF
END

(with apologies for sullying the group with FORTRAN code).

Obviously We need to find and modify all these blocks whenever we add a new
object type, or operation.

I want to write a C++ equivalent, using classes and member functions so that
I can print (or draw, or interrogate, or whatever...) an object without
knowing its type at runtime.

The latest of several attempts is shown below - the compiler complains about
the void* in the PrintObject function, though I thought I'd read that void*
could be used to mean "pointer to something, but I don't know what".

Can this code be modifed to get the effect I want? I'd like to avoid using
pointers to functions if possible.

Thanks!
#include <iostream.h>

// Class declarations
// ------------------

class Square{
public:
void Print();
};

void Square::Print(){
cout << "This is a square";
}

class Circle{
public:
void Print();
};

void Circle::Print(){
cout << "This is a circle";
}

// Print object function
// ---------------------

void PrintObject(void* object){
object->Print();
}

// Main Program
// ------------

int main(){
Square* square;
Circle* circle;

square = new Square;
circle = new Circle;

// Call member functions directly

circle->Print();
square->Print();

// Call member functions through PrintObject function

PrintObject(circle);
PrintObject(square);

return 0;

}

Jul 22 '05 #1
12 2054

"Anthony Jones" <me@privacy.net> wrote in message
news:3K********************@nildram.net...
I want to write a C++ equivalent, using classes and member functions so that I can print (or draw, or interrogate, or whatever...) an object without
knowing its type at runtime.
You mean without knowing its type "at compile time"? It has to be known at
run-time, or you'd never be able to do *anything* with it! :-)

The latest of several attempts is shown below - the compiler complains about the void* in the PrintObject function, though I thought I'd read that void* could be used to mean "pointer to something, but I don't know what".

Yes, you can use a void* to store any other pointer, but you can never *use*
that pointer for anything (dereference it) unless you first cast it back to
whatever it's supposed to be.

// Print object function
// ---------------------

void PrintObject(void* object){
object->Print();
}


What you want to do instead of using a void* is to have a base class from
which all your specific shapes inherit. Then you make a virtual Print
function in the base class, and have each derived class overried that
function to do its own version of printing.

You really need to do some reading up on base classes, inheritance, and
virtual functions before attempting to go further on this.

-Howard


Jul 22 '05 #2

"Anthony Jones" <me@privacy.net> wrote in message
news:3K********************@nildram.net...
I want to write a C++ equivalent, using classes and member functions so that I can print (or draw, or interrogate, or whatever...) an object without
knowing its type at runtime.
You mean without knowing its type "at compile time"? It has to be known at
run-time, or you'd never be able to do *anything* with it! :-)

The latest of several attempts is shown below - the compiler complains about the void* in the PrintObject function, though I thought I'd read that void* could be used to mean "pointer to something, but I don't know what".

Yes, you can use a void* to store any other pointer, but you can never *use*
that pointer for anything (dereference it) unless you first cast it back to
whatever it's supposed to be.

// Print object function
// ---------------------

void PrintObject(void* object){
object->Print();
}


What you want to do instead of using a void* is to have a base class from
which all your specific shapes inherit. Then you make a virtual Print
function in the base class, and have each derived class overried that
function to do its own version of printing.

You really need to do some reading up on base classes, inheritance, and
virtual functions before attempting to go further on this.

-Howard


Jul 22 '05 #3
What you want to do instead of using a void* is to have a base class from
which all your specific shapes inherit. Then you make a virtual Print
function in the base class, and have each derived class overried that
function to do its own version of printing.

You really need to do some reading up on base classes, inheritance, and
virtual functions before attempting to go further on this.


I also suggest that you have a look at some examples
available on the internet.
google for "c++ polymorphism example" ... you might find
some examples with circles and rectangles...

See for example http://onestepback.org/articles/poly/
Jul 22 '05 #4
What you want to do instead of using a void* is to have a base class from
which all your specific shapes inherit. Then you make a virtual Print
function in the base class, and have each derived class overried that
function to do its own version of printing.

You really need to do some reading up on base classes, inheritance, and
virtual functions before attempting to go further on this.


I also suggest that you have a look at some examples
available on the internet.
google for "c++ polymorphism example" ... you might find
some examples with circles and rectangles...

See for example http://onestepback.org/articles/poly/
Jul 22 '05 #5

"Anthony Jones" <me@privacy.net> wrote in message
news:3K********************@nildram.net...

Just a bit of background: I'm one of a group of FORTRAN programmers, looking to switch to C++. We are trying to write a few simple examples to
demonstrate the power of the language to our manager, so he will send us all on a conversion course.

One of many reasons is that our code is littered with examples of:

SUBROUTINE PRINT_ITEM(ITEM, ITEM_TYPE)
IF (ITEM_TYPE .EQ. SQUARE) THEN
CALL PRINT_SQUARE(ITEM)
ELSEIF (ITEM_TYPE .EQ. CIRCLE) THEN
CALL PRINT_CIRCLE(ITEM)
ELSEIF ...
(lots more item types)
ENDIF
END

(with apologies for sullying the group with FORTRAN code).

Obviously We need to find and modify all these blocks whenever we add a new object type, or operation.

I want to write a C++ equivalent, using classes and member functions so that I can print (or draw, or interrogate, or whatever...) an object without
knowing its type at runtime.


For God's sake! VIRTUAL FUNCTIONS

Look it up in your favourite text book. They do exactly what you need.

john
Jul 22 '05 #6

"Anthony Jones" <me@privacy.net> wrote in message
news:3K********************@nildram.net...

Just a bit of background: I'm one of a group of FORTRAN programmers, looking to switch to C++. We are trying to write a few simple examples to
demonstrate the power of the language to our manager, so he will send us all on a conversion course.

One of many reasons is that our code is littered with examples of:

SUBROUTINE PRINT_ITEM(ITEM, ITEM_TYPE)
IF (ITEM_TYPE .EQ. SQUARE) THEN
CALL PRINT_SQUARE(ITEM)
ELSEIF (ITEM_TYPE .EQ. CIRCLE) THEN
CALL PRINT_CIRCLE(ITEM)
ELSEIF ...
(lots more item types)
ENDIF
END

(with apologies for sullying the group with FORTRAN code).

Obviously We need to find and modify all these blocks whenever we add a new object type, or operation.

I want to write a C++ equivalent, using classes and member functions so that I can print (or draw, or interrogate, or whatever...) an object without
knowing its type at runtime.


For God's sake! VIRTUAL FUNCTIONS

Look it up in your favourite text book. They do exactly what you need.

john
Jul 22 '05 #7
Anthony Jones wrote:
Just a bit of background: I'm one of a group of FORTRAN programmers, looking
to switch to C++. We are trying to write a few simple examples to
demonstrate the power of the language to our manager, so he will send us all
on a conversion course.

One of many reasons is that our code is littered with examples of:

SUBROUTINE PRINT_ITEM(ITEM, ITEM_TYPE)
IF (ITEM_TYPE .EQ. SQUARE) THEN
CALL PRINT_SQUARE(ITEM)
ELSEIF (ITEM_TYPE .EQ. CIRCLE) THEN
CALL PRINT_CIRCLE(ITEM)
ELSEIF ...
(lots more item types)
ENDIF
END
Yikes.

(with apologies for sullying the group with FORTRAN code).

Obviously We need to find and modify all these blocks whenever we add a new
object type, or operation.

I want to write a C++ equivalent, using classes and member functions so that
I can print (or draw, or interrogate, or whatever...) an object without
knowing its type at runtime.

The latest of several attempts is shown below - the compiler complains about
the void* in the PrintObject function, though I thought I'd read that void*
could be used to mean "pointer to something, but I don't know what".
Yes, and it also means "no type safety". void* should be avoided, and is
certainly not the right way to accomplish polymorphic behavior (which is
what you are looking for, whether you know that or not).

Can this code be modifed to get the effect I want? I'd like to avoid using
pointers to functions if possible.

Thanks!
#include <iostream.h>
I realize you are new to this, so please understand that I'll point out
any and all errors I spot in your code, regardless of whether they are
relevant to the immediate question. Also, my definition of an 'error'
includes anything that is not defined by the C++ standard, anything that
may behave unexpectedly, or that may behave differently on different
implementations (even if one of the "different implementations" is a
hypothetical implementation that does not actually exist). This is
standard practice for many of the people in this group.

That said, <iostream.h> is not part of the C++ standard. It is old,
pre-standard C++. Standard C++ uses <iostream> (with no .h).

// Class declarations
// ------------------

class Square{
public:
void Print();
};
In order to achieve polymorphic behavior, you need a few things that you
are missing: Inheritance, and virtual functions. Your example involves
shapes. Great, so create a class representing a shape. It will serve as
the base class for you other shapes.

class Shape
{
public:
virtual void Print() = 0;
};

class Square : public Shape
{
public:
void Print();
};

class Circle : public Shape
{
public:
void Print();
};

The "class Square : public Shape" part can be read as "Square IS A
Shape". This is often referred to as the 'is-a' relationship. Squares
and Circles are both types of Shapes, and thus share some of the same
functionality -- in particular, they all have the ability to perform the
'Print' operation.

The 'virtual' qualifier on Shape::Print() just means "this function can
behave differently in different base classes". This allows Square and
Circle to give their own version of Print() that does what they need it
to do. The '= 0' part is a bit more confusing. It has basically 2
effects: 1) It allows Shape to decline to implement Print(). There's no
reasonable way to print a generic shape, so this makes sense. It
essentially requires base classes to provide Print() instead (though a
base class can pull the same trick, passing the burden of implementing
the function onto /its/ base classes). 2) It makes Shape an abstract
class, which is a class that can really only be used as a base class.
You can't create an object of type Shape, because Shape is not a
complete class.

void Square::Print(){
cout << "This is a square";
In modern C++, 'cout' (along with most standard library names) resides
in namespace std. This means that the fully qualified name is std::cout.
You can use this fully-qualified name, or you can put a line like this:

using namespace std;

at the top of your source files, just after the #include directives.
This is sort of the lazy way of doing it, and can be bad in some cases,
but it's the easiest way to get started. There are other options as
well, but you'll learn about that later.

Other than that, no changes are required here.
}

class Circle{
public:
void Print();
};

void Circle::Print(){
cout << "This is a circle";
Same comments as for Square::Print().
}

// Print object function
// ---------------------

void PrintObject(void* object){
Now, you don't want to use void* here. What you want is a function to
print an object. More specifically, a Shape. So try this instead:

void PrintShape(Shape *shape)
{
object->Print();
shape->Print();
}

// Main Program
// ------------

int main(){
Square* square;
Circle* circle;

square = new Square;
circle = new Circle;
Generally, you shouldn't use 'new' unless you absolutely have to. It
tends to be used in real programs that do what you are demonstrating, so
its use here isn't completely inappropriate, but normally when you want
a Square you should just say

Square my_square;

It's also worth noting that a more typical way of doing what you are
doing would be like this:

Shape *square;
Shape *circle;

square = new Square;
circle = new Circle;

In fact, you'd probably be most likely to have a collection of Shape
pointers (in an array, or a container class). Such collections generally
have to be homogeneous, so they can't contain Square pointers and Circle
pointers. Luckily they don't need to, because Shape pointers can point
to Squares, Circles, and any other type that IS A Shape.

// Call member functions directly

circle->Print();
square->Print();

// Call member functions through PrintObject function

PrintObject(circle);
PrintObject(square);
Replace these with the new name 'PrintShape' and you're all set.

return 0;

}


-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Jul 22 '05 #8
Anthony Jones wrote:
Just a bit of background: I'm one of a group of FORTRAN programmers, looking
to switch to C++. We are trying to write a few simple examples to
demonstrate the power of the language to our manager, so he will send us all
on a conversion course.

One of many reasons is that our code is littered with examples of:

SUBROUTINE PRINT_ITEM(ITEM, ITEM_TYPE)
IF (ITEM_TYPE .EQ. SQUARE) THEN
CALL PRINT_SQUARE(ITEM)
ELSEIF (ITEM_TYPE .EQ. CIRCLE) THEN
CALL PRINT_CIRCLE(ITEM)
ELSEIF ...
(lots more item types)
ENDIF
END
Yikes.

(with apologies for sullying the group with FORTRAN code).

Obviously We need to find and modify all these blocks whenever we add a new
object type, or operation.

I want to write a C++ equivalent, using classes and member functions so that
I can print (or draw, or interrogate, or whatever...) an object without
knowing its type at runtime.

The latest of several attempts is shown below - the compiler complains about
the void* in the PrintObject function, though I thought I'd read that void*
could be used to mean "pointer to something, but I don't know what".
Yes, and it also means "no type safety". void* should be avoided, and is
certainly not the right way to accomplish polymorphic behavior (which is
what you are looking for, whether you know that or not).

Can this code be modifed to get the effect I want? I'd like to avoid using
pointers to functions if possible.

Thanks!
#include <iostream.h>
I realize you are new to this, so please understand that I'll point out
any and all errors I spot in your code, regardless of whether they are
relevant to the immediate question. Also, my definition of an 'error'
includes anything that is not defined by the C++ standard, anything that
may behave unexpectedly, or that may behave differently on different
implementations (even if one of the "different implementations" is a
hypothetical implementation that does not actually exist). This is
standard practice for many of the people in this group.

That said, <iostream.h> is not part of the C++ standard. It is old,
pre-standard C++. Standard C++ uses <iostream> (with no .h).

// Class declarations
// ------------------

class Square{
public:
void Print();
};
In order to achieve polymorphic behavior, you need a few things that you
are missing: Inheritance, and virtual functions. Your example involves
shapes. Great, so create a class representing a shape. It will serve as
the base class for you other shapes.

class Shape
{
public:
virtual void Print() = 0;
};

class Square : public Shape
{
public:
void Print();
};

class Circle : public Shape
{
public:
void Print();
};

The "class Square : public Shape" part can be read as "Square IS A
Shape". This is often referred to as the 'is-a' relationship. Squares
and Circles are both types of Shapes, and thus share some of the same
functionality -- in particular, they all have the ability to perform the
'Print' operation.

The 'virtual' qualifier on Shape::Print() just means "this function can
behave differently in different base classes". This allows Square and
Circle to give their own version of Print() that does what they need it
to do. The '= 0' part is a bit more confusing. It has basically 2
effects: 1) It allows Shape to decline to implement Print(). There's no
reasonable way to print a generic shape, so this makes sense. It
essentially requires base classes to provide Print() instead (though a
base class can pull the same trick, passing the burden of implementing
the function onto /its/ base classes). 2) It makes Shape an abstract
class, which is a class that can really only be used as a base class.
You can't create an object of type Shape, because Shape is not a
complete class.

void Square::Print(){
cout << "This is a square";
In modern C++, 'cout' (along with most standard library names) resides
in namespace std. This means that the fully qualified name is std::cout.
You can use this fully-qualified name, or you can put a line like this:

using namespace std;

at the top of your source files, just after the #include directives.
This is sort of the lazy way of doing it, and can be bad in some cases,
but it's the easiest way to get started. There are other options as
well, but you'll learn about that later.

Other than that, no changes are required here.
}

class Circle{
public:
void Print();
};

void Circle::Print(){
cout << "This is a circle";
Same comments as for Square::Print().
}

// Print object function
// ---------------------

void PrintObject(void* object){
Now, you don't want to use void* here. What you want is a function to
print an object. More specifically, a Shape. So try this instead:

void PrintShape(Shape *shape)
{
object->Print();
shape->Print();
}

// Main Program
// ------------

int main(){
Square* square;
Circle* circle;

square = new Square;
circle = new Circle;
Generally, you shouldn't use 'new' unless you absolutely have to. It
tends to be used in real programs that do what you are demonstrating, so
its use here isn't completely inappropriate, but normally when you want
a Square you should just say

Square my_square;

It's also worth noting that a more typical way of doing what you are
doing would be like this:

Shape *square;
Shape *circle;

square = new Square;
circle = new Circle;

In fact, you'd probably be most likely to have a collection of Shape
pointers (in an array, or a container class). Such collections generally
have to be homogeneous, so they can't contain Square pointers and Circle
pointers. Luckily they don't need to, because Shape pointers can point
to Squares, Circles, and any other type that IS A Shape.

// Call member functions directly

circle->Print();
square->Print();

// Call member functions through PrintObject function

PrintObject(circle);
PrintObject(square);
Replace these with the new name 'PrintShape' and you're all set.

return 0;

}


-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Jul 22 '05 #9
On Thu, 8 Apr 2004 19:51:23 +0100 in comp.lang.c++, "Anthony Jones"
<me@privacy.net> wrote,
I want to write a C++ equivalent, using classes and member functions so that
I can print (or draw, or interrogate, or whatever...) an object without
knowing its type at runtime.


This issue is covered in Marshall Cline's C++ FAQ. See the topic
"[20.4] I have a heterogeneous list of objects, and my code needs to do
class-specific things to the objects. Seems like this ought to use
dynamic binding but can't figure it out. What should I do?" It is
always good to check the FAQ before posting. You can get the FAQ at:
http://www.parashift.com/c++-faq-lite/

Jul 22 '05 #10
On Thu, 8 Apr 2004 19:51:23 +0100 in comp.lang.c++, "Anthony Jones"
<me@privacy.net> wrote,
I want to write a C++ equivalent, using classes and member functions so that
I can print (or draw, or interrogate, or whatever...) an object without
knowing its type at runtime.


This issue is covered in Marshall Cline's C++ FAQ. See the topic
"[20.4] I have a heterogeneous list of objects, and my code needs to do
class-specific things to the objects. Seems like this ought to use
dynamic binding but can't figure it out. What should I do?" It is
always good to check the FAQ before posting. You can get the FAQ at:
http://www.parashift.com/c++-faq-lite/

Jul 22 '05 #11
Anthony,

See the few additions/modifications in your code below. You are very close
but only missing a few items. You need to use virtual member functions
rather than simple member functions. Which means you need to derive from an
base class that declares a virtual member function.

"Anthony Jones" <me@privacy.net> wrote in message
news:3K********************@nildram.net...

Just a bit of background: I'm one of a group of FORTRAN programmers, looking to switch to C++. We are trying to write a few simple examples to
demonstrate the power of the language to our manager, so he will send us all on a conversion course.

One of many reasons is that our code is littered with examples of:

SUBROUTINE PRINT_ITEM(ITEM, ITEM_TYPE)
IF (ITEM_TYPE .EQ. SQUARE) THEN
CALL PRINT_SQUARE(ITEM)
ELSEIF (ITEM_TYPE .EQ. CIRCLE) THEN
CALL PRINT_CIRCLE(ITEM)
ELSEIF ...
(lots more item types)
ENDIF
END

(with apologies for sullying the group with FORTRAN code).

Obviously We need to find and modify all these blocks whenever we add a new object type, or operation.

I want to write a C++ equivalent, using classes and member functions so that I can print (or draw, or interrogate, or whatever...) an object without
knowing its type at runtime.

The latest of several attempts is shown below - the compiler complains about the void* in the PrintObject function, though I thought I'd read that void* could be used to mean "pointer to something, but I don't know what".

Can this code be modifed to get the effect I want? I'd like to avoid using
pointers to functions if possible.

Thanks!
#include <iostream.h>

// Class declarations
// ------------------
class Geometry
{
public:
virtual ~Geometry(){} // need a virtual destructor in this case

virtual void Print(){}
};

class Square{
replace with:

class Square : public Geometry{

public:
void Print();
};

void Square::Print(){
cout << "This is a square";
}

class Circle{
replace with:

class Circle : public Geometry{
public:
void Print();
};

void Circle::Print(){
cout << "This is a circle";
}

// Print object function
// ---------------------

void PrintObject(void* object){
object->Print();
}
replace with:

void PrintObject( Geometry* aObjectPtr )
{
aObjectPtr->Print();
}

or better yet:

void PrintObject( Geometry& aObject ) // by reference
{
aObject.Print();
}

// Main Program
// ------------

int main(){
Square* square;
Circle* circle;

square = new Square;
circle = new Circle;

// Call member functions directly

circle->Print();
square->Print();

// Call member functions through PrintObject function

PrintObject(circle);
PrintObject(square);
to use the reference version replace with:

PrintObject( *circle ); // dereference the pointers to get references
PrintObject( *square );

return 0;

}


Better yet is to forego dealing with pointers altogether.

int main()
{
Square lSquare;
Circle lCircle;

lCircle.Print();
lSquare.Print();

PrintObject( lSquare );
PrintObject( lCircle );

return 0;
}

Additionally, since typically a Print function would not modify the state of
it's object, it's best to declare the member function as 'const'. As in:

class Geometry
{
public:
virtual ~Geometry(){}
virtual void Print()const{}
};

And finally to show the real power:

#include <vector>

int main()
{
typedef std::vector<Geometry*> ;

tGeoPtrs lGeoPtrs;

lGeoPtrs.push_back( new Circle );
lGeoPtrs.push_back( new Square );
lGeoPtrs.push_back( new Circle );
lGeoPtrs.push_back( new Square );
lGeoPtrs.push_back( new Circle );

for( tGeoPtrs::iterator lItr = lGeoPtrs.begin() ; lItr != lGeoPtrs.end()
; ++lItr )
{
(*lItr)->Print();

// or

PrintObject( *lItr ); // Pointer overload

// or

PrintObject( **lItr ); // reference overload

delete *lItr; // delete it when we're done

*lItr = NULL;
}

return 0;
}

This is just the beginning of the power/expressivenes advantages of C++
versus Fortran.

Jeff F


Jul 22 '05 #12
Anthony,

See the few additions/modifications in your code below. You are very close
but only missing a few items. You need to use virtual member functions
rather than simple member functions. Which means you need to derive from an
base class that declares a virtual member function.

"Anthony Jones" <me@privacy.net> wrote in message
news:3K********************@nildram.net...

Just a bit of background: I'm one of a group of FORTRAN programmers, looking to switch to C++. We are trying to write a few simple examples to
demonstrate the power of the language to our manager, so he will send us all on a conversion course.

One of many reasons is that our code is littered with examples of:

SUBROUTINE PRINT_ITEM(ITEM, ITEM_TYPE)
IF (ITEM_TYPE .EQ. SQUARE) THEN
CALL PRINT_SQUARE(ITEM)
ELSEIF (ITEM_TYPE .EQ. CIRCLE) THEN
CALL PRINT_CIRCLE(ITEM)
ELSEIF ...
(lots more item types)
ENDIF
END

(with apologies for sullying the group with FORTRAN code).

Obviously We need to find and modify all these blocks whenever we add a new object type, or operation.

I want to write a C++ equivalent, using classes and member functions so that I can print (or draw, or interrogate, or whatever...) an object without
knowing its type at runtime.

The latest of several attempts is shown below - the compiler complains about the void* in the PrintObject function, though I thought I'd read that void* could be used to mean "pointer to something, but I don't know what".

Can this code be modifed to get the effect I want? I'd like to avoid using
pointers to functions if possible.

Thanks!
#include <iostream.h>

// Class declarations
// ------------------
class Geometry
{
public:
virtual ~Geometry(){} // need a virtual destructor in this case

virtual void Print(){}
};

class Square{
replace with:

class Square : public Geometry{

public:
void Print();
};

void Square::Print(){
cout << "This is a square";
}

class Circle{
replace with:

class Circle : public Geometry{
public:
void Print();
};

void Circle::Print(){
cout << "This is a circle";
}

// Print object function
// ---------------------

void PrintObject(void* object){
object->Print();
}
replace with:

void PrintObject( Geometry* aObjectPtr )
{
aObjectPtr->Print();
}

or better yet:

void PrintObject( Geometry& aObject ) // by reference
{
aObject.Print();
}

// Main Program
// ------------

int main(){
Square* square;
Circle* circle;

square = new Square;
circle = new Circle;

// Call member functions directly

circle->Print();
square->Print();

// Call member functions through PrintObject function

PrintObject(circle);
PrintObject(square);
to use the reference version replace with:

PrintObject( *circle ); // dereference the pointers to get references
PrintObject( *square );

return 0;

}


Better yet is to forego dealing with pointers altogether.

int main()
{
Square lSquare;
Circle lCircle;

lCircle.Print();
lSquare.Print();

PrintObject( lSquare );
PrintObject( lCircle );

return 0;
}

Additionally, since typically a Print function would not modify the state of
it's object, it's best to declare the member function as 'const'. As in:

class Geometry
{
public:
virtual ~Geometry(){}
virtual void Print()const{}
};

And finally to show the real power:

#include <vector>

int main()
{
typedef std::vector<Geometry*> ;

tGeoPtrs lGeoPtrs;

lGeoPtrs.push_back( new Circle );
lGeoPtrs.push_back( new Square );
lGeoPtrs.push_back( new Circle );
lGeoPtrs.push_back( new Square );
lGeoPtrs.push_back( new Circle );

for( tGeoPtrs::iterator lItr = lGeoPtrs.begin() ; lItr != lGeoPtrs.end()
; ++lItr )
{
(*lItr)->Print();

// or

PrintObject( *lItr ); // Pointer overload

// or

PrintObject( **lItr ); // reference overload

delete *lItr; // delete it when we're done

*lItr = NULL;
}

return 0;
}

This is just the beginning of the power/expressivenes advantages of C++
versus Fortran.

Jeff F


Jul 22 '05 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

15
by: Nick Coghlan | last post by:
Thought some folks here might find this one interesting. No great revelations, just a fairly sensible piece on writing readable code :) The whole article:...
12
by: Anthony Jones | last post by:
Just a bit of background: I'm one of a group of FORTRAN programmers, looking to switch to C++. We are trying to write a few simple examples to demonstrate the power of the language to our manager,...
5
by: Jeff Greenberg | last post by:
Not an experienced c++ programmer here and I've gotten myself a bit stuck. I'm trying to implement a class lib and I've run into a sticky problem that I can't solve. I'd appreciate any help that I...
5
by: Adrian | last post by:
I am trying to pass the address of a C++ function into a Fortran routine to enable the Fortran routine to call this C++ function. I have to do it this way as our build process does not allow...
3
by: David Dvali | last post by:
Hello. I have one small program which I need to convert in C#. The original source codes are written in Fortran 77. Can anybody advice me what is the easy way to do this task? Or may be there...
2
by: | last post by:
Help! I'm new to c++, and am breaking my teeth on MS Visual C++ (bundled within Visual Studio .NET 2003). Am trying to link simple c++ code to fortran dlls created in Compaq Visual Fortran (v6.1)....
8
by: Daz | last post by:
Hi all! This question may hopefully spark a little debate, but my problem is this: I am sure it's not just me who struggles to think up names for variables. Obviously, thinking up a name...
12
by: StephQ | last post by:
I face the following problem. I wrote a poor's man plotting function: computePlot. This function append some x-values belonging to step and the correseponding f( x ) (for a given const member...
7
by: ghulands | last post by:
I am having trouble implementing some function pointer stuff in c++ An object can register itself for many events void addEventListener(CFObject *target, CFEventHandler callback, uint8_t...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.