derived classes compile error

xyzabc's Avatar, Join Date: Apr 2009
Go4Expert Member
I cannot seem to understand the errors I am getting when trying to compile a program that I have written. Any help appreciated..the problem states

Create a base class named Rectangle that contains length and width data members (doubles). From this class derive a class named Box having an additional date member named depth (double) and will have access to derived variables length and width. The base Rectangle class should have a constructor function prototype (initialize: double=1.0 and double=1.0) and an area() function that returns the area of the rectangle. The derived Box class should have a constructor function prototype (initialize: double=10.0, double=20.0,double=30.0), a volume function that returns the volume of the box, and an override function named area() that returns the surface area of the box. In function main(), declare an object of Rectangle class r and declare an object of Box class called b(3,4,5). Then display r.area(), b.area(), and b.volume().

Code:
 
#include<iostream>
using namespace std;
class Rectangle
{
      protected:
                double length;
                double width;
      public:
             Rectangle::Rectangle(double = 1.0,double = 1.0);
             double area();
             
};
double Rectangle::area()
{
       return(length * width);
}
class Box : public Rectangle
{
      protected:
                double depth;
      
      public:
              Box::Box(double 10.0,double 20.0,double 30.0);
              double volume();
              double area();
};
Box::Box(double l,double w,double d);
{
   length = l;
   width = w;
   depth=d;
}
double Box::volume();
{
       return(l * w * depth);
}
double Box::area();
{
       return(length * width);
}
int main()
{
    Rectangle r;
    Box b(3,4,5);
    
    cout<<r.area()<<endl;
    cout<<b.area()<<endl;
    cout<<b.volume()<<endl;
    
    system("pause");
    return 0;
}
0
xyzabc's Avatar, Join Date: Apr 2009
Go4Expert Member
sorry the errors are::

39 prototype for `Box::Box(double, double, double)' does not match any in class `Box'
27 candidates are: Box::Box(const Box&)
39 declaration of `Box::Box(double, double, double)' outside of class is not definition
0
xpi0t0s's Avatar, Join Date: Aug 2004
Mentor
Change the line
Box::Box(double 10.0,double 20.0,double 30.0);

to
Box(double l,double w,double d);

and remove the semicolons off the Box::Box, Box::volume and Box::area function bodies. (You didn't put one after main, which is correct, so it's not clear why you think you should put one after other functions.)

In a function prototype you specify variable names, not values.
Function bodies should not include a semicolon between the close bracket and open brace.
0
xyzabc's Avatar, Join Date: Apr 2009
Go4Expert Member
Quote:
Originally Posted by xpi0t0s View Post
Change the line
Box::Box(double 10.0,double 20.0,double 30.0);

to
Box(double l,double w,double d);

and remove the semicolons off the Box::Box, Box::volume and Box::area function bodies. (You didn't put one after main, which is correct, so it's not clear why you think you should put one after other functions.)

In a function prototype you specify variable names, not values.
Function bodies should not include a semicolon between the close bracket and open brace.
ok this brings the question of how to initialize the values to 10.0 20.0 30.0 as stated in the original problem. I was thinking like this
Code:
 Box(double l,double w,double d)
              {
                         length=10.0;
                         width=20.0;
                         depth=30.0;
              }
Is this correct?
The functions give the answers
1
6000
6000

so I am assuming this would work.
0
xpi0t0s's Avatar, Join Date: Aug 2004
Mentor
The idea of a function is that you pass in values that you want the function to operate on. If length, width and depth are always going to be initialised to 10,20 and 30 then you don't need to pass anything into Box(). But if you want to set length to l etc, then you need to do length=l; instead of length=20.0;, and when you call Box, give it those values, e.g. Box(10,20,30).

I suggest you get the Rectangle class working first, then you can start work on Box. Take it a step at a time. "Rectangle::Rectangle(double = 1.0,double = 1.0);" - hmm, you seem to be taking "initialize: double=1.0 and double=1.0" rather too literally. The Rectangle constructor should take no parameters if you're always going to be using fixed values, or it should take two named parameters (e.g. Rectangle(double l,double w), then you can assign those values to length and width, i.e. length=1.0 if you're using fixed values, or length=l if you're using parameters.

In a way it's similar to maths; if a function is not dependent on specific variables then it's pointless passing them in. If f() is dependent on x but not y, then you would define f(x) rather than f(x,y); you could set f(x,y)=x^2, but then everyone would ask "why y?".

Correct results don't always mean the code is correct. Does the code give the correct results for different size boxes and rectangles?

You haven't specified the Rectangle::Rectangle function body anywhere, just a prototype. I'm not sure why the code works at all; Rectangle::length and Rectangle::width haven't been initialised anywhere. What compiler are you using?
0
xyzabc's Avatar, Join Date: Apr 2009
Go4Expert Member
Quote:
Originally Posted by xpi0t0s View Post
The idea of a function is that you pass in values that you want the function to operate on. If length, width and depth are always going to be initialised to 10,20 and 30 then you don't need to pass anything into Box(). But if you want to set length to l etc, then you need to do length=l; instead of length=20.0;, and when you call Box, give it those values, e.g. Box(10,20,30).

I suggest you get the Rectangle class working first, then you can start work on Box. Take it a step at a time. "Rectangle::Rectangle(double = 1.0,double = 1.0);" - hmm, you seem to be taking "initialize: double=1.0 and double=1.0" rather too literally. The Rectangle constructor should take no parameters if you're always going to be using fixed values, or it should take two named parameters (e.g. Rectangle(double l,double w), then you can assign those values to length and width, i.e. length=1.0 if you're using fixed values, or length=l if you're using parameters.

In a way it's similar to maths; if a function is not dependent on specific variables then it's pointless passing them in. If f() is dependent on x but not y, then you would define f(x) rather than f(x,y); you could set f(x,y)=x^2, but then everyone would ask "why y?".

Correct results don't always mean the code is correct. Does the code give the correct results for different size boxes and rectangles?

You haven't specified the Rectangle::Rectangle function body anywhere, just a prototype. I'm not sure why the code works at all; Rectangle::length and Rectangle::width haven't been initialised anywhere. What compiler are you using?
I am using dev c++ 4.9.9.2..

So the
Rectangle::Rectangle(double=1.0,double=1.0)
should be more like
Rectangle::Rectangle(double l,double w)?

How would I initialize length and width to 1.0 using
Rectangle::length
Rectangle::width
since neither of these are functions?

sorry for so many questions as I am a beginner.

Let me repost the code so you can see the update and see if what I did was what you meant

Code:
#include<iostream>
using namespace std;
class Rectangle
{
      protected:
             double length;
             double width;
      public:
             Rectangle::Rectangle(double= 1.0,double = 1.0);
             double area();
             
};

Rectangle::Rectangle(double l,double w)
{
             length = l;
             width = w;
}

double Rectangle::area()
{
     return(length * width);
}

class Box : public Rectangle
{
    protected:
             double depth;
                
    public:
     Box(double l,double w,double d)
     {
             length=l;
             width=w;
             depth=d;
     }
             double volume();
             double area();
              
};
 
double Box::volume()
{
       return(length * width * depth);
}
double Box::area()
{
       return(length * width);
}
int main()
{
    Rectangle r;
    Box b(3.0,4.0,5.0);
    
    cout<<r.area()<<endl;
    cout<<b.area()<<endl;
    cout<<b.volume()<<endl;
    
    system("pause");
    return 0;
}
0
xpi0t0s's Avatar, Join Date: Aug 2004
Mentor
Here's what I think it should be:
Code:
class Rectangle
{
      protected:
             double length;
             double width;
      public:
             Rectangle::Rectangle(double l,double w);
             double area();
             
};

Rectangle::Rectangle(double l,double w)
{
             length = l;
             width = w;
}

and in main:

Rectangle r(1.0, 1.0);
However the ambiguous task specification has me baffled. What have the values 10, 20 and 30 got to do with anything? Are they meant to be default values? (which would mean Box r; would be equivalent to Box r(10,20,30); ) Similarly what have the two 1.0 values got to do with anything? Are they defaults, or are we (maybe for the sake of learning) defining a Rectangle object that will only ever compute the area of 1x1 squares, which will always be just 1? It would seem to make more sense to me for Rectangle to be generic, so you could define Rectangle r1, r2(10,2), r3(100,50), etc.
0
xyzabc's Avatar, Join Date: Apr 2009
Go4Expert Member
Quote:
Originally Posted by xpi0t0s View Post
Here's what I think it should be:
Code:
class Rectangle
{
      protected:
             double length;
             double width;
      public:
             Rectangle::Rectangle(double l,double w);
             double area();
 
};
 
Rectangle::Rectangle(double l,double w)
{
             length = l;
             width = w;
}
 
and in main:
 
Rectangle r(1.0, 1.0);
However the ambiguous task specification has me baffled. What have the values 10, 20 and 30 got to do with anything? Are they meant to be default values? (which would mean Box r; would be equivalent to Box r(10,20,30); ) Similarly what have the two 1.0 values got to do with anything? Are they defaults, or are we (maybe for the sake of learning) defining a Rectangle object that will only ever compute the area of 1x1 squares, which will always be just 1? It would seem to make more sense to me for Rectangle to be generic, so you could define Rectangle r1, , etc.
The 10,20,30 are just values that my professor threw into the problem for default values. I definately see where you are coming from and would have to agree that it would make more sense to just do r2(10,2), r3(100,50) etc. Again though the problem states
" In function main(), declare an object of Rectangle class r and declare an object of Box class called b(3,4,5). Then display r.area(), b.area(), and b.volume()."
so this means that he is expecting just two objects to be declared.
Rectangle r;
Box b(3,4,5)

When I change the code to what you suggested above it gives me compiler errors similar to the ones I posted in my first/second post.

In constructor `Box::Box(double)':
no matching function for call to `Rectangle::Rectangle()'
candidates are: Rectangle::Rectangle(const Rectangle&)
note C:\Users\Chris\Documents\C++\cemHW13.cpp:11 Rectangle::Rectangle(double, double)

I am feeling the way he is wanting us to do this problem is making things more difficult then they should be.
0
xyzabc's Avatar, Join Date: Apr 2009
Go4Expert Member
Would this be the correct formula to calculate the surface area of Box b?

Code:
double Box::area()
{
       return((2*length * width)+(2*width * depth)+(2*length*depth));
}

Last edited by xyzabc; 19Apr2009 at 11:05..
0
xpi0t0s's Avatar, Join Date: Aug 2004
Mentor
> When I change the code to what you suggested above it gives me compiler errors...

Yes, you will need to change the Box usage of Rectangle to reflect the constructor. The error occurs because Rectangle::Rectangle() doesn't exist (you've changed it to Rectangle::Rectangle(double,double)).

> I am feeling the way he is wanting us to do this problem is making things more difficult then they should be.

Depends. I don't know the context of the course, i.e. what you've done in the past. Maybe Rectangle was only ever meant to operate for 1x1 squares and we're now looking at class derivation. The Box class will work for boxes of any size so I don't understand why Rectangle is so limited. Possibly the point is that even though Rectangle only works for 1x1 squares due to there only being a parameterless constructor that initialises length and width to 1,1, this doesn't limit Box to 1x1xN cuboids.

> Would this be the correct formula to calculate the surface area of Box b?

Yes. For extra smartie points you could show you understand how to access overloaded functions from classes lower down the object hierarchy by changing that to
Code:
return((2*Rectangle::area())+(2*width * depth)+(2*length*depth));
and if he makes a comment about lower performance ask him about code profiling and what he thinks about premature optimisation <grin>