Topic: What is wrong with my virtual classes and destructors?


Author: andrew@ambra.dk (Leif Andrew Rump)
Date: 16 Jan 92 10:11:49 GMT
Raw View
Please look into this - even if you are not be able to answer the
question asked:

    "What is wrong with my virtual classes and destructors?"

You may have some comments on my programming style or what ever.
Please send the whole thing!

The program has only been tested using Borland C++ 2.0 and it use
Borland C graphics. I've made some ifdef's so the program use
iostreams instead - just undefine BC_GRAPHIC in graphic.cpp.

Remember to change this line in graphic.cpp to your need:
#define   GRAPHIC_PATH  "c:\\applic\\borlandc\\bgi"

Choose one of these:
//#define BC_GRAPHIC  // Use Borland C(++) graphics
//#undef  BC_GRAPHIC  // Use standard C++ iostreams

If VIRTUAL is not defined then the code is compiled as described in
a lot of C++ books, but I get the compiler error below - why?

//#define VIRTUAL     // Make arc & ellipse virtual in arcellipse
//#undef  VIRTUAL     // Make circle virtual in arc & ellipse

ARCELLIPSE: Cannot find acircle::acircle() to initialize base class in
function arcellipse::arcellipse(const int, const int, ..., const int)

Define VIRTUAL to remove the error.

If DESTRUCTOR is not defined then only one destructor is defined, but
when it is executed I get the runtime error below - why?

//#define DESTRUCTOR  // Define destructors in all classes in the tree
//#undef  DESTRUCTOR  // Define only a destructor in the base class (alocation)

Resulting in: "Pure virtual function called"

Define DESTRUCTOR to see a full C++ graphics program!

Please E-mail _ANY_ comments.

Andrew

Keep an eye on this signature - it will automagically change in the near future

Leif Andrew Rump, AmbraSoft A/S, Stroedamvej 50, DK-2100 Copenhagen OE, Denmark
UUCP: andrew@ambra.dk, Phone: +45 39 27 11 77, Fax: +45 39 27 99

---- Cut Here and unpack ----
#!/bin/sh
# This is graphic, a shell archive (shar 3.21)
# made 01/16/1992 09:49 UTC by andrew@ambush
# Source directory /usr/acct/andrew/G
#
# existing files will NOT be overwritten
#
# This shar contains:
# length  mode       name
# ------ ---------- ------------------------------------------
#   5174 -rw-rw-rw- graphic.cpp
#   1145 -rw-rw-rw- arc.h
#   1383 -rw-rw-rw- arcellip.h
#    800 -rw-rw-rw- box.h
#    852 -rw-rw-rw- circle.h
#   1008 -rw-rw-rw- ellipse.h
#    280 -rw-rw-rw- graphic.h
#    952 -rw-rw-rw- line.h
#    859 -rw-rw-rw- location.h
#    974 -rw-rw-rw- point.h
#
if touch 2>&1 | fgrep '[-amc]' > /dev/null
 then TOUCH=touch
 else TOUCH=true
fi
# ============= graphic.cpp ==============
if test X"$1" != X"-c" -a -f 'graphic.cpp'; then
 echo "File already exists: skipping 'graphic.cpp'"
else
echo "x - extracting graphic.cpp (Text)"
sed 's/^X//' << 'SHAR_EOF' > graphic.cpp &&
X// graphic.cpp
X
X#define   GRAPHIC_PATH  "c:\\applic\\borlandc\\bgi"
X
X//#define BC_GRAPHIC  // Use Borland C(++) graphics
X//#undef  BC_GRAPHIC  // Use standard C++ iostreams
X
X//#define VIRTUAL     // Make arc & ellipse virtual in arcellipse
X//#undef  VIRTUAL     // Make circle virtual in arc & ellipse
X/*
XARCELLIPSE: Cannot find acircle::acircle() to initialize base class in
Xfunction arcellipse::arcellipse(const int, const int, ..., const int)
X*/
X
X//#define DESTRUCTOR  // Define destructors in all classes in the tree
X//#undef  DESTRUCTOR  // Define only a destructor in the base class (alocation)
X/*
XResulting in: "Pure virtual function called"
X*/
X
X#include <stdlib.h>
X#include <stdio.h>
X#include <conio.h>
X
X#ifdef  BC_GRAPHIC
X  #include <graphics.h>
X#else   BC_GRAPHIC
X  #include <iostream.h>
X#endif  BC_GRAPHIC
X
X// There is two outstanding questions in this code (Look for "WHY"!):
X// 1: Why is a virtual destructor needed through the whole tree (LOCATION.H)
X// 2: Why is virtual classes "initialised" more than once (ARCELLIP.H)
X
X#include "point.h"
X#include "line.h"
X#include "box.h"
X#include "circle.h"
X#include "ellipse.h"
X#include "arc.h"
X#include "arcellipse.h"
X
X/*
X  location --- point -+- line ----- box
X                      |
X                      +- circle -+- ellipse -+
X                                 |           |
X                                 +- arc -----+- arcellipse
X*/
X
Xvoid variables(void)
X{
X#ifdef  BC_GRAPHIC
X  int maxx = getmaxx();
X  int maxy = getmaxy();
X#else   BC_GRAPHIC
X  int maxx = 200;
X  int maxy = 100;
X#endif  BC_GRAPHIC
X
X  int halfx = maxx / 2;
X  int halfy = maxy / 2;
X
X#ifndef BC_GRAPHIC
X  cout << "\napoint\n";
X#endif  BC_GRAPHIC
X  apoint      point(halfx, halfy);
X
X#ifndef BC_GRAPHIC
X  getch();
X  cout << "\naline\n";
X#endif  BC_GRAPHIC
X  aline       line(0, 0, maxx, maxy);
X
X#ifndef BC_GRAPHIC
X  getch();
X  cout << "\nabox\n";
X#endif  BC_GRAPHIC
X  abox        box(0, 0, maxx, maxy);
X
X#ifndef BC_GRAPHIC
X  getch();
X  cout << "\nacircle\n";
X#endif  BC_GRAPHIC
X  acircle     circle(halfx, halfy, min(maxx, maxy)); // BUG: min only C !C++
X
X#ifndef BC_GRAPHIC
X  getch();
X  cout << "\naellipse\n";
X#endif  BC_GRAPHIC
X  aellipse    ellipse(halfx, halfy, halfx / 2, halfy / 2);
X
X#ifndef BC_GRAPHIC
X  getch();
X  cout << "\naarc\n";
X#endif  BC_GRAPHIC
X  aarc        arc(halfx, halfy, 45, 45 + 180, halfy);
X
X#ifndef BC_GRAPHIC
X  getch();
X  cout << "\naarcellipse\n";
X#endif  BC_GRAPHIC
X  aarcellipse arcellipse(halfx, halfy, 45, 45 + 180, halfx, halfy);
X
X  getch();
X  point.show();
X  getch();
X  line.show();
X  getch();
X  box.show();
X  getch();
X  circle.show();
X  getch();
X  ellipse.show();
X  getch();
X  arc.show();
X  getch();
X  arcellipse.show();
X  getch();
X
X  point.hide();
X  getch();
X  line.hide();
X  getch();
X  box.hide();
X  getch();
X  circle.hide();
X  getch();
X  ellipse.hide();
X  getch();
X  arc.hide();
X  getch();
X  arcellipse.hide();
X  getch();
X
X  point.show();
X  line.show();
X  box.show();
X  circle.show();
X  ellipse.show();
X  arc.show();
X  arcellipse.show();
X  getch();
X}
X
Xvoid pointers(void)
X{
X#ifdef  BC_GRAPHIC
X  int maxx = getmaxx();
X  int maxy = getmaxy();
X#else   BC_GRAPHIC
X  int maxx = 200;
X  int maxy = 100;
X#endif  BC_GRAPHIC
X
X  int halfx = maxx / 2;
X  int halfy = maxy / 2;
X
X  alocation *graphics[] = {new apoint(halfx, halfy),
X                           new aline(0, 0, maxx, maxy),
X                           new abox(0, 0, maxx, maxy),
X                           new acircle(halfx, halfy, min(maxx, maxy)),
X                           new aellipse(halfx, halfy, halfx / 2, halfy / 2),
X                           new aarc(halfx, halfy, 45, 45 + 180, halfy),
X                           new aarcellipse(halfx, halfy, 45, 45 + 180,
X                                           halfx, halfy)};
X
X  getch();
X  graphics[0]->show();
X  getch();
X  graphics[1]->show();
X  getch();
X  graphics[2]->show();
X  getch();
X  graphics[3]->show();
X  getch();
X  graphics[4]->show();
X  getch();
X  graphics[5]->show();
X  getch();
X  graphics[6]->show();
X  getch();
X
X  graphics[0]->hide();
X  getch();
X  graphics[1]->hide();
X  getch();
X  graphics[2]->hide();
X  getch();
X  graphics[3]->hide();
X  getch();
X  graphics[4]->hide();
X  getch();
X  graphics[5]->hide();
X  getch();
X  graphics[6]->hide();
X  getch();
X
X  graphics[0]->show();
X  graphics[1]->show();
X  graphics[2]->show();
X  graphics[3]->show();
X  graphics[4]->show();
X  graphics[5]->show();
X  graphics[6]->show();
X  getch();
X
X  for (int i = 0; i < sizeof(graphics) / sizeof(graphics[0]); i++)
X    delete graphics[i];
X}
X
Xint main(void)
X{
X#ifdef  BC_GRAPHIC
X  int gdriver = DETECT, gmode, errorcode;
X
X  initgraph(&gdriver, &gmode, GRAPHIC_PATH);
X
X  /* read result of initialization */
X  errorcode = graphresult();
X
X  if (errorcode != grOk)  /* an error occurred */
X  {
X    printf("Graphics error: %s\n", grapherrormsg(errorcode));
X    printf("Press any key to halt:");
X    getch();
X    exit(1);             /* return with error code */
X  }
X
X  settextjustify(CENTER_TEXT, CENTER_TEXT);
X  outtextxy(getmaxx() / 2, getmaxy() / 2, "Please press a key to see changes!");
X#endif  BC_GRAPHIC
X
X  variables();
X  pointers();
X  getch();
X
X#ifdef  BC_GRAPHIC
X  closegraph();
X#endif  BC_GRAPHIC
X  return 0;
X}
X
SHAR_EOF
$TOUCH -am 0116104992 graphic.cpp &&
chmod 0666 graphic.cpp ||
echo "restore of graphic.cpp failed"
set `wc -c graphic.cpp`;Wc_c=$1
if test "$Wc_c" != "5174"; then
 echo original size 5174, current size $Wc_c
fi
fi
# ============= arc.h ==============
if test X"$1" != X"-c" -a -f 'arc.h'; then
 echo "File already exists: skipping 'arc.h'"
else
echo "x - extracting arc.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > arc.h &&
X#ifndef  __AARC_H__
X#define  __AARC_H__
X
X#include "circle.h"
X
X#ifdef  VIRTUAL
Xclass aarc : public acircle
X#else   VIRTUAL
Xclass aarc : public virtual acircle
X#endif  VIRTUAL
X{
X  int start, stop;
X
X  virtual void draw(const int color) const
X  {
X#ifdef  BC_GRAPHIC
X    int oldcolor = getcolor();
X
X    if (color != oldcolor)
X      setcolor(color);
X    arc(getx(), gety(), getstart(), getstop(), getr());
X    if (color != oldcolor)
X      setcolor(oldcolor);
X#else   BC_GRAPHIC
X    cout << "aarc::draw (" << getx() << ',' << gety() << '-'
X         << getstart() << ',' << getstop() << ':'
X         << getr() << ';' << color << ")\n";
X#endif  BC_GRAPHIC
X  }
X
Xpublic :
X  aarc(const int newx, const int newy, const int newstart, const int newstop,
X       const int newr) : acircle(newx, newy, newr),
X      start(newstart), stop(newstop)
X  {
X#ifndef BC_GRAPHIC
X    cout << "aarc::aarc (" << start << ',' << stop << ")\n";
X#endif  BC_GRAPHIC
X  }
X  virtual getstart(void) const
X  {
X    return start;
X  }
X  virtual getstop(void) const
X  {
X    return stop;
X  }
X#ifdef  DESTRUCTOR
X  virtual ~aarc(void)
X  {
X    (void)hide();
X  }
X#endif  DESTRUCTOR
X};
X
X#endif
X
SHAR_EOF
$TOUCH -am 0116104292 arc.h &&
chmod 0666 arc.h ||
echo "restore of arc.h failed"
set `wc -c arc.h`;Wc_c=$1
if test "$Wc_c" != "1145"; then
 echo original size 1145, current size $Wc_c
fi
fi
# ============= arcellip.h ==============
if test X"$1" != X"-c" -a -f 'arcellip.h'; then
 echo "File already exists: skipping 'arcellip.h'"
else
echo "x - extracting arcellip.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > arcellip.h &&
X#ifndef  __AARCELLIPSE_H__
X#define  __AARCELLIPSE_H__
X
X#include "ellipse.h"
X#include "arc.h"
X
X// Even though the class aarc is declared virtual the constructor
X// calls apoint and all it's decendants more than once through
X// aellipse & aarc and they DON't share the same data!?! WHY?
X
X#ifdef  VIRTUAL
Xclass aarcellipse : public virtual aellipse, public virtual aarc
X#else   VIRTUAL
Xclass aarcellipse : public aellipse, public aarc
X#endif  VIRTUAL
X{
X  virtual void draw(const int color) const
X  {
X#ifdef  BC_GRAPHIC
X    int oldcolor = getcolor();
X
X    if (color != oldcolor)
X      setcolor(color);
X    ellipse(getx(), gety(), getstart(), getstop(), getr(), getry());
X    if (color != oldcolor)
X      setcolor(oldcolor);
X#else   BC_GRAPHIC
X    cout << "aarcellipse::draw (" << getx() << ',' << gety() << '-'
X         << getstart() << ',' << getstop() << ':'
X         << getr() << ',' << getry() << ';' << color << ")\n";
X#endif  BC_GRAPHIC
X  }
X
Xpublic :
X  aarcellipse(const int newx, const int newy, const int newstart,
X              const int newstop, const int newr, const int newry) :
X             aellipse(newx, newy, newr, newry),
X             aarc(newx, newy, newstart, newstop, newr)
X  {
X#ifndef BC_GRAPHIC
X    cout << "aarcellipse::aarcellipse\n";
X#endif  BC_GRAPHIC
X  }
X#ifdef  DESTRUCTOR
X  virtual ~aarcellipse(void)
X  {
X    (void)hide();
X  }
X#endif  DESTRUCTOR
X};
X
X#endif
X
SHAR_EOF
$TOUCH -am 0116104292 arcellip.h &&
chmod 0666 arcellip.h ||
echo "restore of arcellip.h failed"
set `wc -c arcellip.h`;Wc_c=$1
if test "$Wc_c" != "1383"; then
 echo original size 1383, current size $Wc_c
fi
fi
# ============= box.h ==============
if test X"$1" != X"-c" -a -f 'box.h'; then
 echo "File already exists: skipping 'box.h'"
else
echo "x - extracting box.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > box.h &&
X#ifndef  __ABOX_H__
X#define  __ABOX_H__
X
X#include "line.h"
X
Xclass abox : public aline
X{
X  virtual void draw(const int color) const
X  {
X#ifdef  BC_GRAPHIC
X    int oldcolor = getcolor();
X
X    if (color != oldcolor)
X      setcolor(color);
X    rectangle(getx(), gety(), getx0(), gety0());
X    if (color != oldcolor)
X      setcolor(oldcolor);
X#else   BC_GRAPHIC
X    cout << "abox::draw (" << getx() << ',' << gety() << '-'
X         << getx0() << ',' << gety0() << ';' << color << ")\n";
X#endif  BC_GRAPHIC
X  }
X
Xpublic :
X  abox(const int newx, const int newy, const int newx0, const int newy0) :
X      aline(newx, newy, newx0, newy0)
X  {
X#ifndef BC_GRAPHIC
X    cout << "abox::abox\n";
X#endif  BC_GRAPHIC
X  }
X#ifdef  DESTRUCTOR
X  virtual ~abox(void)
X  {
X    (void)hide();
X  }
X#endif  DESTRUCTOR
X};
X
X#endif
X
SHAR_EOF
$TOUCH -am 0116104292 box.h &&
chmod 0666 box.h ||
echo "restore of box.h failed"
set `wc -c box.h`;Wc_c=$1
if test "$Wc_c" != "800"; then
 echo original size 800, current size $Wc_c
fi
fi
# ============= circle.h ==============
if test X"$1" != X"-c" -a -f 'circle.h'; then
 echo "File already exists: skipping 'circle.h'"
else
echo "x - extracting circle.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > circle.h &&
X#ifndef  __ACIRCLE_H__
X#define  __ACIRCLE_H__
X
X#include "point.h"
X
Xclass acircle : public apoint
X{
X  int r;
X
X  virtual void draw(const int color) const
X  {
X#ifdef  BC_GRAPHIC
X    int oldcolor = getcolor();
X
X    if (color != oldcolor)
X      setcolor(color);
X    circle(getx(), gety(), getr());
X    if (color != oldcolor)
X      setcolor(oldcolor);
X#else   BC_GRAPHIC
X    cout << "acircle::draw (" << getx() << ',' << gety() << ':'
X         << getr() << ';' << color << ")\n";
X#endif  BC_GRAPHIC
X  }
X
Xpublic :
X  acircle(const int newx, const int newy, const int newr) :
X         apoint(newx, newy), r(newr)
X  {
X#ifndef BC_GRAPHIC
X    cout << "acircle::acircle (" << r << ")\n";
X#endif  BC_GRAPHIC
X  }
X  virtual int getr(void) const
X  {
X    return r;
X  }
X#ifdef  DESTRUCTOR
X  virtual ~acircle(void)
X  {
X    (void)hide();
X  }
X#endif  DESTRUCTOR
X};
X
X#endif
X
SHAR_EOF
$TOUCH -am 0116104292 circle.h &&
chmod 0666 circle.h ||
echo "restore of circle.h failed"
set `wc -c circle.h`;Wc_c=$1
if test "$Wc_c" != "852"; then
 echo original size 852, current size $Wc_c
fi
fi
# ============= ellipse.h ==============
if test X"$1" != X"-c" -a -f 'ellipse.h'; then
 echo "File already exists: skipping 'ellipse.h'"
else
echo "x - extracting ellipse.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > ellipse.h &&
X#ifndef  __AELLIPSE_H__
X#define  __AELLIPSE_H__
X
X#include "circle.h"
X
X#ifdef  VIRTUAL
Xclass aellipse : public acircle
X#else   VIRTUAL
Xclass aellipse : public virtual acircle
X#endif
X{
X  int ry;
X
X  virtual void draw(const int color) const
X  {
X#ifdef  BC_GRAPHIC
X    int oldcolor = getcolor();
X
X    if (color != oldcolor)
X      setcolor(color);
X    ellipse(getx(), gety(), 0, 360, getr(), getry());
X    if (color != oldcolor)
X      setcolor(oldcolor);
X#else   BC_GRAPHIC
X    cout << "aellipse::draw (" << getx() << ',' << gety() << ':'
X         << getr() << ',' << getry() << ';' << color << ")\n";
X#endif  BC_GRAPHIC
X  }
X
Xpublic :
X  aellipse(const int newx, const int newy, const int newr, const int newry) :
X          acircle(newx, newy, newr), ry(newry)
X  {
X#ifndef BC_GRAPHIC
X    cout << "aellipse::aellipse (" << ry << ")\n";
X#endif  BC_GRAPHIC
X  }
X  virtual int getry(void) const
X  {
X    return ry;
X  }
X#ifdef  DESTRUCTOR
X  virtual ~aellipse(void)
X  {
X    (void)hide();
X  }
X#endif  DESTRUCTOR
X};
X
X#endif
X
SHAR_EOF
$TOUCH -am 0116104292 ellipse.h &&
chmod 0666 ellipse.h ||
echo "restore of ellipse.h failed"
set `wc -c ellipse.h`;Wc_c=$1
if test "$Wc_c" != "1008"; then
 echo original size 1008, current size $Wc_c
fi
fi
# ============= graphic.h ==============
if test X"$1" != X"-c" -a -f 'graphic.h'; then
 echo "File already exists: skipping 'graphic.h'"
else
echo "x - extracting graphic.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > graphic.h &&
X#ifndef  __GRAFIK_H__
X#define  __GRAFIK_H__
X
Xenum bool {false, true};
X
Xinline int min(int a, int b)  // Why isn't this defined under C++?
X{
X   return (a < b) ? a : b;
X}
X
Xinline long min(long a, long b)  // Why isn't this defined under C++?
X{
X   return (a < b) ? a : b;
X}
X
X#endif
X
SHAR_EOF
$TOUCH -am 0116104392 graphic.h &&
chmod 0666 graphic.h ||
echo "restore of graphic.h failed"
set `wc -c graphic.h`;Wc_c=$1
if test "$Wc_c" != "280"; then
 echo original size 280, current size $Wc_c
fi
fi
# ============= line.h ==============
if test X"$1" != X"-c" -a -f 'line.h'; then
 echo "File already exists: skipping 'line.h'"
else
echo "x - extracting line.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > line.h &&
X#ifndef  __ALINE_H__
X#define  __ALINE_H__
X
X#include "point.h"
X
Xclass aline : public apoint
X{
X  int x0, y0;
X
X  virtual void draw(const int color) const
X  {
X#ifdef  BC_GRAPHIC
X    int oldcolor = getcolor();
X
X    if (color != oldcolor)
X      setcolor(color);
X    line(getx(), gety(), getx0(), gety0());
X    if (color != oldcolor)
X      setcolor(oldcolor);
X#else   BC_GRAPHIC
X    cout << "aline::draw (" << getx() << ',' << gety() << '-'
X         << getx0() << ',' << gety0() << ';' << color << ")\n";
X#endif  BC_GRAPHIC
X  }
X
Xpublic :
X  aline(const int newx, const int newy, const int newx0, const int newy0) :
X       apoint(newx, newy), x0(newx0), y0(newy0)
X  {
X#ifndef BC_GRAPHIC
X    cout << "aline::aline (" << x0 << ',' << y0 << ")\n";
X#endif  BC_GRAPHIC
X  }
X  int getx0(void) const
X  {
X    return x0;
X  }
X  int gety0(void) const
X  {
X    return y0;
X  }
X#ifdef  DESTRUCTOR
X  virtual ~aline(void)
X  {
X    (void)hide();
X  }
X#endif  DESTRUCTOR
X};
X
X#endif
X
SHAR_EOF
$TOUCH -am 0116104392 line.h &&
chmod 0666 line.h ||
echo "restore of line.h failed"
set `wc -c line.h`;Wc_c=$1
if test "$Wc_c" != "952"; then
 echo original size 952, current size $Wc_c
fi
fi
# ============= location.h ==============
if test X"$1" != X"-c" -a -f 'location.h'; then
 echo "File already exists: skipping 'location.h'"
else
echo "x - extracting location.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > location.h &&
X#ifndef  __ALOCATION_H__
X#define  __ALOCATION_H__
X
X#include "graphic.h"
X
Xclass alocation
X{
X  bool visible;
X
X  virtual void draw(const int color) const = 0;
X
Xpublic :
X  alocation() : visible(false)
X  {
X#ifndef BC_GRAPHIC
X    cout << "alocation::alocation (" << visible << ")\n";
X#endif  BC_GRAPHIC
X  }
X  virtual bool show(void)
X  {
X    bool temp = visible;
X
X    if (!visible)
X#ifdef  BC_GRAPHIC
X      draw(getcolor());
X#else   BC_GRAPHIC
X      draw(true);
X#endif  BC_GRAPHIC
X    visible = true;
X    return temp;
X  }
X  virtual bool hide(void)
X  {
X    bool temp = visible;
X
X    if (visible)
X#ifdef  BC_GRAPHIC
X      draw(getbkcolor());
X#else   BC_GRAPHIC
X      draw(false);
X#endif  BC_GRAPHIC
X    visible = false;
X    return temp;
X  }
X  virtual ~alocation(void)
X  { // Shouldn't this destructor handle all descendants? WHY NOT?
X    (void)hide();
X  }
X};
X
X#endif
X
SHAR_EOF
$TOUCH -am 0116104392 location.h &&
chmod 0666 location.h ||
echo "restore of location.h failed"
set `wc -c location.h`;Wc_c=$1
if test "$Wc_c" != "859"; then
 echo original size 859, current size $Wc_c
fi
fi
# ============= point.h ==============
if test X"$1" != X"-c" -a -f 'point.h'; then
 echo "File already exists: skipping 'point.h'"
else
echo "x - extracting point.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > point.h &&
X#ifndef  __APOINT_H__
X#define  __APOINT_H__
X
X#include "location.h"
X
Xclass apoint : public alocation
X{
X  int x, y;
X
X  virtual void draw(const int color) const
X  {
X#ifdef  BC_GRAPHIC
X    int oldcolor = getcolor();
X
X    if (color != oldcolor)
X      setcolor(color);
X    line(getx() - 10, gety() - 10, getx() + 10, gety() + 10);
X    line(getx() - 10, gety() + 10, getx() + 10, gety() - 10);
X//  putpixel(getx(), gety(), color);
X    if (color != oldcolor)
X      setcolor(oldcolor);
X#else   BC_GRAPHIC
X    cout << "apoint::draw (" << getx() << ',' << gety() << ';'
X         << color << ")\n";
X#endif  BC_GRAPHIC
X  }
X
Xpublic :
X  apoint(const int newx, const int newy) : x(newx), y(newy)
X  {
X#ifndef BC_GRAPHIC
X    cout << "apoint::apoint (" << x << ',' << y << ")\n";
X#endif  BC_GRAPHIC
X  }
X  int getx(void) const
X  {
X    return x;
X  }
X  int gety(void) const
X  {
X    return y;
X  }
X#ifdef  DESTRUCTOR
X  virtual ~apoint(void)
X  {
X    (void)hide();
X  }
X#endif  DESTRUCTOR
X};
X
X#endif
X
SHAR_EOF
$TOUCH -am 0116104392 point.h &&
chmod 0666 point.h ||
echo "restore of point.h failed"
set `wc -c point.h`;Wc_c=$1
if test "$Wc_c" != "974"; then
 echo original size 974, current size $Wc_c
fi
fi
exit 0




Author: andrew@ambra.dk (Leif Andrew Rump)
Date: 17 Jan 92 10:26:26 GMT
Raw View
I posted a message yesterday with a shar-file containing an
C++ example (Message-ID: <1992Jan16.101149.19776@ambra.dk>).
I forgot my last question:

Why is: location, point & circle initialized twice, first through
ellipse and then through arc even though arc and ellipse is defined
as virtual classes in arcellipse!?!


  location --- point -+- line ----- box
                      |
                      +- circle -+- ellipse -+
                                 |           |
                                 +- arc -----+- arcellipse


If you didn't get the shar file, feel free to ask for another copy.

Andrew

Keep an eye on this signature - it will automagically change in the near future

Leif Andrew Rump, AmbraSoft A/S, Stroedamvej 50, DK-2100 Copenhagen OE, Denmark
UUCP: andrew@ambra.dk, Phone: +45 39 27 11 77, Fax: +45 39 27 99