1. We have moved from vBulletin to XenForo and you are viewing the site in the middle of the move. Though the functional aspect of everything is working fine, we are still working on other changes including the new design on Xenforo.
    Dismiss Notice

derived classes compile error

Discussion in 'C++' started by xyzabc, Apr 17, 2009.

  1. xyzabc

    xyzabc New Member

    Joined:
    Apr 13, 2009
    Messages:
    21
    Likes Received:
    0
    Trophy Points:
    0
    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;
    }
        
        
     
  2. xyzabc

    xyzabc New Member

    Joined:
    Apr 13, 2009
    Messages:
    21
    Likes Received:
    0
    Trophy Points:
    0
    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
     
  3. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,012
    Likes Received:
    203
    Trophy Points:
    0
    Occupation:
    Senior Support Engineer
    Location:
    England
    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.
     
  4. xyzabc

    xyzabc New Member

    Joined:
    Apr 13, 2009
    Messages:
    21
    Likes Received:
    0
    Trophy Points:
    0
    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.
     
  5. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,012
    Likes Received:
    203
    Trophy Points:
    0
    Occupation:
    Senior Support Engineer
    Location:
    England
    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?
     
  6. xyzabc

    xyzabc New Member

    Joined:
    Apr 13, 2009
    Messages:
    21
    Likes Received:
    0
    Trophy Points:
    0
    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;
    }
     
    
     
  7. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,012
    Likes Received:
    203
    Trophy Points:
    0
    Occupation:
    Senior Support Engineer
    Location:
    England
    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.
     
  8. xyzabc

    xyzabc New Member

    Joined:
    Apr 13, 2009
    Messages:
    21
    Likes Received:
    0
    Trophy Points:
    0
    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.
     
  9. xyzabc

    xyzabc New Member

    Joined:
    Apr 13, 2009
    Messages:
    21
    Likes Received:
    0
    Trophy Points:
    0
    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: Apr 19, 2009
  10. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,012
    Likes Received:
    203
    Trophy Points:
    0
    Occupation:
    Senior Support Engineer
    Location:
    England
    > 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>
     
  11. xyzabc

    xyzabc New Member

    Joined:
    Apr 13, 2009
    Messages:
    21
    Likes Received:
    0
    Trophy Points:
    0
    Thanks for the "smartie points" code help :D. I will see what he has to say about that.

    I still am confused though on one thing. The 10.0, 20.0,30.0 isn't even going to be used at all in my program since Box b(3,4,5) has been declared in main, correct? Considering I am calling b.volume() and b.area(). So I don't understand why he even wants us to declare the 10,20,30 values. The Box b(3,4,5) will override those values everytime wont they?

    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::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(length * width * depth);
    }
    double Box::area()
    {
           return((2*Rectangle::area())+(2*width * depth)+(2*length*depth));
    }
    int main()
    {
        Rectangle r;
        Box b(3.0,4.0,5.0);
        
        cout<<"The area of the rectangle is: "<<r.area()<<endl;
        cout<<"\nThe volume of box b is: " <<b.volume()<<endl;
        cout<<"\nThe surface area of box b is: "<<b.area()<<endl;
        cout<<endl;
        
        system("pause");
        return 0;
    }
    
     
  12. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,012
    Likes Received:
    203
    Trophy Points:
    0
    Occupation:
    Senior Support Engineer
    Location:
    England
    They could be default values. That means that you can miss off those parameters when you declare a Box and you will get the default. Example: Box a, b(1), c(1,2), d(1,2,3); will define 4 boxes of dimensions a=10,20,30; b=1,20,30; c=1,2,30; d=1,2,3 and all four will invoke the Box::Box(double l=10, double w=20, double d=30) constructor.

    nitpicks:
    - include the variable names in the constructor prototype. e.g double l=30.0, rather than double=30.0. It's clearer to read that way.
    - you don't need the Box:: prefix on function names when the function is written within the class definition, i.e. public: Box::Box(...) should be shortened to public: Box(...). Again this is for clearer reading; you would only expect to see Box(...) and the addition of Box:: will make you wonder why that's been added.
    The Box:: prefix is needed for stuff written outside the class definition, i.e.:
    Code:
    class foo {
      void func1(); // no prefix needed
      void func2() { /* ... */ } // no prefix needed
    };
    void foo::func1() { /* ... */ } // prefix is needed here to distinguish between foo::func1() and a global function func1().
    void func1() { /* ... */ } // this declares a global function func1() that has nothing to do with the one in class foo
    
     
  13. xyzabc

    xyzabc New Member

    Joined:
    Apr 13, 2009
    Messages:
    21
    Likes Received:
    0
    Trophy Points:
    0
    Ok thanks again for all your help with this problem. Have a great day.
     

Share This Page