When I run this code and create an instance of cylinderType by passing four parameters, debugger shows the height I want but, radius=x=y=0. So when I call method printVolume() on this object, it displays '0'.
Am I missing something important with inheritance?
Thank you~
#include <iostream>
using namespace std;
class circleType
{
public:
circleType();
circleType(double r);
double getArea() const;
private:
double radius;
};
class cylinderType : public circleType
{
public:
cylinderType(double h, double r);
void printVolume() const;
private:
double height;
};
int main()
{
cylinderType cylinderA(2, 4);
cylinderA.printVolume();
return 0;
};
circleType::circleType()
{
radius = 0;
};
circleType::circleType(double r)
{
radius = r;
};
double circleType::getArea() const
{
return (3.14 * radius* radius);
};
cylinderType::cylinderType(double h, double r)
{
circleType::circleType(r);
height = h;
};
void cylinderType::printVolume() const
{
cout << (circleType::getArea() * height);
};
Related
Hello i am trying to create a simple program in C++ and I have problems in linking the files. The error is undefined reference to my copy constructors in the classes. I checked the linking and I can't find any errors in the header file.
I tried messing around with the copy constructors but still no solution. when i comment the copy constructors, the program compiles.
Error message:
/tmp/cc5KI4Dx.o: In function `CenteredShape::CenteredShape(CenteredShape const&)':
Shapes.cpp:(.text+0x1c0): undefined reference to `Shape::Shape()'
/tmp/cc5KI4Dx.o: In function `RegularPolygon::RegularPolygon(RegularPolygon const&)':
Shapes.cpp:(.text+0x258): undefined reference to `CenteredShape::CenteredShape()'
/tmp/cc5KI4Dx.o: In function `Circle::Circle(Circle const&)':
Shapes.cpp:(.text+0x388): undefined reference to `CenteredShape::CenteredShape()'
/tmp/cc5KI4Dx.o: In function `Rectangle::Rectangle(Rectangle const&)':
Shapes.cpp:(.text+0x42c): undefined reference to `RegularPolygon::RegularPolygon()'
/tmp/cc5KI4Dx.o: In function `Square::Square(Square const&)':
Shapes.cpp:(.text+0x576): undefined reference to `RegularPolygon::RegularPolygon()'
collect2: error: ld returned 1 exit status
testshapes.cpp
#include "Shapes.h"
int main(int argc, char** argv) {
Circle c("first circle", 3, 4, 7);
RegularPolygon r("TRIANGLE", 1, 1, 3);
r.printName();
c.printName();
}
Shapes.h
/*
Classic shape examples: an inheritance tree in a geometric context
*/
#ifndef __SHAPES_H
#define __SHAPES_H
#include <string>
class Shape { // base class
private: // private access modifier: could also be protected
std::string name; // every shape will have a name
public:
Shape(const std::string&); // builds a shape with a name
Shape(); // empty shape
Shape(const Shape&);
// copy constructor
void printName() const ; // prints the name
//setters
void setName(std::string newName);
//getters
std::string getName();
};
class CenteredShape : public Shape { // inherits from Shape
private:
double x,y; // the center of the shape
public:
CenteredShape(const std::string&, double, double); // usual three constructors
CenteredShape();
CenteredShape(const CenteredShape&);
//setters
void move(double, double); // moves the shape, i.e. it modifies it center
//getters
double getX();
double getY();
};
class RegularPolygon : public CenteredShape { // a regular polygon is a centered_shape with a number of edges
private:
int EdgesNumber;
public:
RegularPolygon(const std::string&, double, double, int);
RegularPolygon();
RegularPolygon(const RegularPolygon&);
//setters
void setEdgesNumber(int newEdgesNumber);
//getter
int getEdgesNumber();
};
class Circle : public CenteredShape { // a Circle is a shape with a center and a radius
private:
double Radius;
public:
Circle(const std::string&, double, double, double);
Circle();
Circle(const Circle&);
//methods
double perimeter();
double area();
//setters
void setRadius(double newRadius);
//getters
double getRadius();
};
class Rectangle : public RegularPolygon { // a Rectange is a shape with edges
private:
double length;
double width;
public:
Rectangle(const std::string& n, double nx, double ny, double nwidth,double nheight);
Rectangle();
Rectangle(const Rectangle&);
//methods
double perimeter();
double area();
//setters
void setLength(double newLength);
void setWidth(double newWidth);
//getters
double getLength();
double getWidth();
};
class Square : public RegularPolygon { // a Square is a shape with edges
private:
double side;
public:
Square(const std::string& n, double nx, double ny, double nside);
Square();
Square(const Square&);
//methods
double perimeter();
double area();
//setters
void setSide(double newSide);
//getters
double getSide();
};
#endif
Shapes.cpp
// please refer to shapes.h for methods documentation
#include <iostream>
#include "Shapes.h"
using namespace std;
//------------------------------------------------------
Shape::Shape(const string& n) : name(n) {
}
// copy constructor
Shape::Shape(const Shape &shp)
{
name = shp.name;
}
void Shape::printName() const {
cout << name << endl;
}
void Shape::setName(string newName)
{
name = newName;
}
string Shape::getName()
{
return name;
}
//---------------------------------------------------------
void CenteredShape::move(double nx, double ny)
{
x=nx;
y=ny;
}
double CenteredShape::getX()
{
return x;
}
double CenteredShape::getY()
{
return y;
}
CenteredShape::CenteredShape(const string &n, double nx, double ny): Shape(n) {
x = nx;
y = ny;
}
CenteredShape::CenteredShape(const CenteredShape &cshp)
{
x=cshp.x;
y=cshp.y;
}
//-----------------------------------------------------------------------------------
RegularPolygon::RegularPolygon(const string& n, double nx, double ny, int nl) : CenteredShape(n,nx,ny)
{
EdgesNumber = nl;
}
RegularPolygon::RegularPolygon(const RegularPolygon ®p)
{
EdgesNumber=regp.EdgesNumber;
}
void RegularPolygon::setEdgesNumber(int newEdgesNumber)
{
EdgesNumber=newEdgesNumber;
}
int RegularPolygon::getEdgesNumber()
{
return EdgesNumber;
}
//----------------------------------------------------------------------------------
double Circle::perimeter()
{
return (2*3.14*Radius);
}
double Circle::area()
{
return(3.14*Radius*Radius);
}
void Circle::setRadius(double newRadius)
{
Radius=newRadius;
}
double Circle::getRadius()
{
return Radius;
}
Circle::Circle(const string& n, double nx, double ny, double r) : CenteredShape(n,nx,ny)
{
Radius = r;
}
Circle::Circle(const Circle &cr)
{
Radius=cr.Radius;
}
//------------------------------------------------------------------------------------
Rectangle::Rectangle(const string &n, double nx, double ny, double nwidth, double nheight) : RegularPolygon(n,nx,ny,4)
{
length=nheight;
width=nwidth;
}
Rectangle::Rectangle(const Rectangle &rect)
{
length=rect.length;
width=rect.width;
}
double Rectangle::perimeter()
{
return (2*(length+width));
}
double Rectangle::area()
{
return (length*width);
}
void Rectangle::setLength(double newLength)
{
length = newLength;
}
void Rectangle::setWidth(double newWidth)
{
width = newWidth;
}
double Rectangle::getLength()
{
return length;
}
double Rectangle::getWidth()
{
return width;
}
//------------------------------------------------------------------------------
Square::Square(const string& n, double nx, double ny, double nside):RegularPolygon(n,nx,ny,4)
{
side=nside;
}
Square::Square(const Square &sqr)
{
side = sqr.side;
}
double Square::perimeter()
{
return (side*4);
}
double Square::area()
{
return (side*side);
}
void Square::setSide(double newSide)
{
side=newSide;
}
double Square::getSide()
{
return side;
}
I dont understand the diffrence between Polymorphism and Inheritance... They Litterarly do the same thing...
Simple Example Of Polymorphism:
class shape {
public:
void setValues(int height_, int width_) {
height = height_, width = width_;
}
protected:
int height, width;
private:
};
class rectangle :public shape, public ThreeDView{
public:
int area() {
return(shape::height*shape::width);
}
float threeDArea() {
return(((shape::height*shape::width)/2)*(std::cos(Z_LENGTH)));
}
};
class ThreeDView{
public:
void setZLength(int value) {
Z_LENGTH = value;
}
int setCompact(bool ans) {
compact = ans;
}
float getZLength() {
return Z_LENGTH;
}
bool getCOMPACT() {
return compact;
}
protected:
float Z_LENGTH;
bool compact;
private:
unsigned char ZCHAR = 'Z';
};
class triangle :public shape {
public:
int area() {
return((shape::height * shape::width) / 2);
}
};
int main(){
rectangle rect2;
triangle trng2;
shape *poly = &rect2;
shape *poly2 = &trng2;
poly->setValues(2,3);
poly2->setValues(5,4);
std::cout << "AREA : " << trng1.area() << "AREA RECT : \n" <<rect1.area() << std::endl;
}
Above example translated to Inheritance:
class shape {
public:
void setValues(int height_, int width_) {
height = height_, width = width_;
}
protected:
int height, width;
private:
};
class rectangle :public shape, public ThreeDView{
public:
int area() {
return(shape::height*shape::width);
}
float threeDArea() {
return(((shape::height*shape::width)/2)*(std::cos(Z_LENGTH)));
}
};
class triangle :public shape {
public:
int area() {
return((shape::height * shape::width) / 2);
}
};
int main(){
rectangle rect2;
triangle trng2;
rect2.setValues(2,3);
trng2.setValues(5,4);
std::cout << "AREA : " << trng1.area() << "AREA RECT : \n" <<rect1.area() << std::endl;
}
Please tell me diffrence. Honestly i dont even see the use of Polymorphism! Thanks for helping!
Here's a version of your first example, that actually uses polymorphism:
#include <iostream>
#include <string>
class shape
{
public:
void setValues(int height_, int width_)
{
height = height_;
width = width_;
}
virtual int area() = 0; // This is needed for polymorphism to work
virtual std::string name() = 0;
protected:
int height;
int width;
};
class rectangle : public shape
{
public:
int area()
{
return height * width;
}
std::string name()
{
return "Rectangle";
}
};
class triangle :public shape
{
public:
int area()
{
return height * width / 2;
}
std::string name()
{
return "Triangle";
}
};
void print_area(shape& poly)
{
std::cout << poly.name() << ' ' << poly.area() << '\n';
}
int main()
{
rectangle rect;
triangle trng;
rect.setValues(2, 3);
trng.setValues(5, 4);
print_area(rect);
print_area(trng);
}
The first big change is that I declare the virtual function area in the shape class. For polymorphism to work, the functions must be declared in the base class as virtual. The "assignment" to 0 is simply telling the compiler that it's an abstract function, and the child-classes must override that function.
The second big change is that I use a function to print the area, one that only takes a reference to the base shape class. You must use references or pointers to the base class for polymrphism to work, not use the actual objects directly like in your example.
This works as expected.
I've been writing a program for CS class that's supposed to get the X and Y coordinates from the user, as well as the length of a square and the height of the cube, and it should then calculate the area of the square and the surface area and volume of the cube (plus some coordinates stuff but that's not a pressing issue right now)
I've written the test file and it compiled successfully, but I've been getting very long answers for the square and cube properties that are obviously wrong. Can anyone point out whatever logical errors I might have or if I have the access specification and relationship between the classes wrong?
Point.h
class Point
{
protected:
double Xint, Yint;
public:
Point();
void setX(double);
void setY(double);
double getX() const;
double getY() const;
};
Point.ccp
Point::Point()
{
Xint = 0;
Yint = 0;
}
void Point::setX(double x)
{ Xint = x; }
void Point::setY(double y)
{ Yint = y; }
double Point::getX() const
{ return Xint; }
double Point::getY() const
{ return Yint; }
Square.h
#include "Point.h"
class Square : public Point
{
protected:
Point lowerLeft;
double sideLength;
public:
Square(double sideLength, double x, double y) : Point()
{
sideLength = 0.0;
x = 0.0;
y = 0.0;
}
void setLowerLeft(double, double);
void setSideLength(double);
double getSideLength() const;
double getSquareArea() const;
};
Square.ccp
#include "Square.h"
void Square::setLowerLeft(double x, double y)
{
lowerLeft.setX(x);
lowerLeft.setY(y);
}
void Square::setSideLength(double SL)
{ sideLength = SL; }
double Square::getSideLength() const
{ return sideLength; }
// Calculate the area of square
double Square::getSquareArea() const
{ return sideLength * sideLength; }
Cube.h
#include "Square.h"
class Cube : public Square
{
protected:
double height;
double volume;
public:
Cube(double height, double volume) : Square(sideLength, Xint, Yint)
{
height = 0.0;
volume = 0.0;
}
double getSurfaceArea() const;
double getVolume() const;
};
Cube.ccp
#include "Cube.h"
// Redefine GetSquareArea to calculate the cube's surface area
double Cube::getSurfaceArea() const
{ return Square::getSquareArea() * 6; }
// Calculate the volume
double Cube::getVolume() const
{ return getSquareArea() * height; }
"Can anyone point out whatever logical errors I might have or if I have the access specification and relationship between the classes wrong?"
Well, from our well known 3-dimensional geometry a cube is made up from exactly 6 squares.
So how do you think inheriting a Cube class from a Square actually should work well?
You can easily define a Cube class by means of a fixed Point (e.g. the upper, left, front corner) and a fixed size of the edge length.
If you really want and need to, you can add a convenience function for your Cube class, that returns all of the 6 Squares it consist of in 3 dimensional space:
class Cube {
public:
Cube(const Point& upperLeftFrontCorner, double edgeLength);
std::array<Square,6> getSides() const;
};
Both base classes, Arc and Lines, are derived from class Shape.
The compiler says Ojbect b1 "error: shape is ambiguous". I know that two instances of Shape are being created, but don't know how to resolve it?
Graph_lib::Box b1(Point,100,100), 100,100);
win1.attach(b1);
This class will be able to draw a box with rounded corners. I just wrote the code for the Box Lines part, I didn't get to the Arc yet since this won't even work.
//------------------------------------------------------------------------------
struct Box : Lines , Arc {
Box(Point xy, int ww, int hh);
void Top_segment();
void Bottom_segment();
void Left_side_segment();
void Right_side_segment();
void draw_lines() const;
int height() const { return h; }
int width() const { return w; }
private:
int h; // height
int w; // width
double width_tenth; //10% of the width that will calculate the length to remove from each side to make room for the arcs
};
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
Box::Box(Point xy, int ww, int hh): w(ww), h(hh)
{
width_tenth = (xy.x + w) * 0.10;
if (h<=0 || w<=0) error("Bad box: non-positive side");
}
//------------------------------------------------------------------------------
void Box::Top_segment()
{
double top_seg_begin_w; //where the line segment will begin after deducting 10% of w;
double top_seg_end_w; //where the line segment will end after deducting 10% of w;
top_seg_begin_w = xy.x + width_tenth;
top_seg_end_w = (xy.x + w) - width_tenth;
Lines::add(Point(top_seg_begin_w,xy.y),Point(top_seg_end_w,xy.y));
}
//------------------------------------------------------------------------------
void Box::Bottom_segment()
{
double bottom_seg_begin_w;
double bottom_seg_end_w;
bottom_seg_begin_w = xy.x + width_tenth;
bottom_seg_end_w = (xy.x + w) - width_tenth;
double y_bottom = xy.y + h;
Lines::add(Point(bottom_seg_begin_w,y_bottom),Point(bottom_seg_end_w,y_bottom));
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void Box::Left_side_segment()
{
double left_seg_begin_h;
double left_seg_end_h;
left_seg_begin_h = xy.y + width_tenth;
left_seg_end_h = (xy.y + h) - width_tenth;
double x_left = xy.x;
Lines::add(Point(x_left,left_seg_begin_h),Point(x_left,left_seg_end_h));
}
//------------------------------------------------------------------------------
void Box::Right_side_segment()
{
double right_seg_begin_h;
double right_seg_end_h;
right_seg_begin_h = xy.y + width_tenth;
right_seg_end_h = (xy.y + h) - width_tenth;
double x_right = xy.x + w;
Lines::add(Point(x_right,right_seg_begin_h),Point(x_right,right_seg_end_h));
}
//------------------------------------------------------------------------------
Use virtual inheritance for classes Lines and Arc. For example
class Lines : virtual public Shape
{
//...
};
class Arc : virtual public Shape
{
//...
};
I have made two files that are MathUtils.h
#include "iostream"
and MathUtils.cpp
#include "MathUtils.h"
using namespace std;
//Box class .....................
class Box
{
private:
double length; // Length of a box
double breadth; // Breadth of a box
double height; // Height of a box
public:
void setParameters(int l,int b,int h);
int volume();
int area();
};
void Box::setParameters(int l, int b, int h)
{
length=l;
breadth=b;
height=h;
}
int Box::volume()
{
return length*breadth*height;
}
int Box::area()
{
return (2*(length*breadth) + 2*(breadth*height) + 2*(height*length));
}
//sphere class................
class Sphere
{
private:
double pi=3.14;
double r;
public:
void setParameters(int radius);
int volume();
int area();
};
void Sphere::setParameters(int radius)
{
r=radius;
}
int Sphere::volume()
{
return (4/3)*pi*r*r;
}
int Sphere::area()
{
return 4*pi*r*r;
}
How can we use this file in my project could any one help me.I have never use c++ files in my project so I want to know how can we use Box and Sphere class object in other viewController file.
Thanks!.
You define your classes in the .h file.
For your example, move:
class Box
{
private:
double length; // Length of a box
double breadth; // Breadth of a box
double height; // Height of a box
public:
void setParameters(int l,int b,int h);
int volume();
int area();
};
class Sphere
{
private:
double pi=3.14;
double r;
public:
void setParameters(int radius);
int volume();
int area();
};
to mathutils.h and add #include "mathutils.h" to your viewController file. Your member functions for Box should still be in mathutils.c
A function in your view controller can then make use of it:
{
Box b;
b.setParameters(1,2,3);
int v = b.volume();
int a = b.area();
}