My code isn't working. I'm trying simple inheritance Shape as base class and two classes under Shape "Two Dimension" and "Three Dimension" and shapes under that classes. Here's my code but when I try to define a new class as Triangle it gives me error LNK2001 LNK1120. It looks complicated but I must get area, volume and perimeter for every each object.
My full error:
Severity Code Description Project File Line Suppression State
Error LNK2001 unresolved external symbol "public: virtual double __thiscall TwoDimensionShape::Area(void)" (?Area#TwoDimensionShape##UAENXZ) Shape c:\Users\aleyn\documents\visual studio 2015\Projects\Shape\Shape\Source.obj 1
That's .h
#pragma once
#define M_PI 3.14159265358979323846
class Shape
{
private:
double width, height, depth;
public:
Shape(double w, double h, double d);
virtual void Display() = 0;
virtual double Area() = 0;
virtual double Perimeter() = 0;
virtual double Volume() = 0;
};
class TwoDimensionShape: public Shape
{
public:
TwoDimensionShape(double w, double h, double d = 0) :
Shape(w, h, d)
{
}
double Area();
double Perimeter();
double Volume();
void Display();
};
class ThreeDimensionShape: public Shape
{
private:
double width, height, depth;
public:
ThreeDimensionShape(double w, double h, double d) :
Shape(w, h, d)
{
depth = d;
}
double Area();
double Volume();
double Perimeter();
void Display();
};
class Triangle: public TwoDimensionShape
{
private:
double side1, side2, base;
public:
Triangle(double w, double h, double d = 0) :
TwoDimensionShape(w, h, d)
{
}
double Area()
{
return Area() / 2;
}
void setTriangleSides(double s1, double s2, double b);
double Perimeter()
{
return side1, side2, base;
}
double Volume()
{
return 0;
}
};
class Square: public TwoDimensionShape
{
public:
Square(double w, double h, double d = 0) :
TwoDimensionShape(w, h, d)
{
}
double Volume()
{
return 0;
}
};
class Rectangle: public TwoDimensionShape
{
public:
Rectangle(double w, double h, double d = 0) :
TwoDimensionShape(w, h, d)
{
}
double Volume()
{
return 0;
}
};
class Circle: public TwoDimensionShape
{
private:
double radius;
public:
Circle(double r, double a = 0, double d = 0) :
TwoDimensionShape(r, a, d)
{
radius = r;
}
double Area()
{
return M_PI * (radius) * (radius);
}
double Perimeter()
{
return 2 * M_PI * radius;
}
double Volume()
{
return 0;
}
};
class Sphere: public ThreeDimensionShape
{
private:
double radius;
public:
Sphere(double r, double a = 0, double b = 0) :
ThreeDimensionShape(r, a, b)
{
radius = r;
}
double Volume()
{
return (4 / 3 * M_PI * (radius * radius * radius));
}
double Area()
{
return 4 * M_PI * radius * radius;
}
double Perimeter()
{
return 0;
}
};
class Cylinder: public ThreeDimensionShape
{
private:
double radius, height;
public:
Cylinder(double r, double h, double a = 0) :
ThreeDimensionShape(r, h, a)
{
}
double Volume()
{
return M_PI * radius * radius * height;
}
double Area()
{
return (2 * M_PI * radius * height) + 2 * M_PI * radius * radius;
}
double Perimeter()
{
return 0;
}
};
class Cone: public ThreeDimensionShape
{
private:
double radius, height, side;
public:
Cone(double r, double h, double s) :
ThreeDimensionShape(r, h, s)
{
}
double Volume()
{
return 1 / 3 * M_PI * radius * radius * height;
}
double Area()
{
return (M_PI * radius * side) + M_PI * radius * radius;
}
double Perimeter()
{
return 0;
}
};
class RectPrism: public ThreeDimensionShape
{
public:
RectPrism(double w, double h, double d) :
ThreeDimensionShape(w, h, d)
{
}
double Area();
double Volume();
double Perimeter();
};
my .cpp
#include "Shape.h"
#include <iostream>
using namespace std;
Shape::Shape(double w, double h, double d)
{
width = w;
height = h;
depth = d;
}
double Shape::Area()
{
return width * height;
}
double Shape::Perimeter()
{
return (width + height) * 2;
}
double Shape::Volume()
{
return width * height * depth;
}
double ThreeDimensionShape::Area()
{
return (2 * (height * width) + 2 * (depth * width) + 2 * (depth * height));
}
double ThreeDimensionShape::Volume()
{
return width * height * depth;
}
double ThreeDimensionShape::Perimeter()
{
return (4 * width + 4 * height + 4 * depth);
}
void Triangle::setTriangleSides(double s1, double s2, double b)
{
side1 = s1;
side2 = s2;
base = b;
}
void TwoDimensionShape::Display()
{
cout << "Perimeter: " << Perimeter() << endl;
cout << "Area: " << Area() << endl;
cout << "Volume: " << Volume() << endl;
}
main .cpp
#include <iostream>
#include "Shape.h"
using namespace std;
int main()
{
Triangle t1(8, 5, 0);
system("pause");
return 0;
}
the error message says it all
LNK2001 unresolved external symbol "public: virtual double __thiscall TwoDimensionShape::Area(void)"
You have not written TwoDimenionalShape::Area
In your header file you promised to write one, but you didnt
Related
I am trying to calculate area of all shapes (rectangle, rhombus, triangle, circle) through using virtual and override methods. But when I execute the code it returns 1 for the area for all shapes even though I have tried with the rectangle to alter it to input the given area multiple times in int main() it still only outputs "My figure type is My area is 1 My figure type is Triangle My area is 1 My figure type is Circle My area is 1 My figure type is Rhombus My area is 1"
#include <iostream>
#include <string>
#include <cmath>
using namespace std;
class Figure
{
protected:
double x;
double y;
string type;
public:
Figure(double m_x, double m_y) : x{ m_x }, y{ m_y } {};
virtual double area(double x, double y) { return 0; };
Figure(double m_x, double m_y, double x = 0, double y = 0) { m_x = x; m_y = y; }
virtual void Print() const final;
Figure(const Figure& obj);
Figure() {};
};
class Rectangle : public Figure
{
public:
Rectangle(double x, double y)
{
this->x = x;
this->y = y;
type = " Rectangle";
double area();
}
double area(double x, double y) override {
return x * y;
}
Rectangle() {};
};
class Triangle : public Figure
{
public:
Triangle(double x, double y)
{
this->x = x;
this->y = y;
type = " Triangle";
double area();
}
double area(double x, double y)override {
return x * y / 2;
}
Triangle() {};
};
class Circle : public Figure
{
public:
Circle(double x, double y)
{
this->x = x;
this->y = y;
type = " Circle";
double area();
}
double area(double x, double y)override {
return pow(x, 2) * 3.14;
}
Circle() {};
};
class Rhombus : public Figure
{
public:
Rhombus(double x, double y)
{
this->x = x; this->y = y; type = " Rhombus"; double area();
}
double area(double x, double y)override {
return x * y / 2;
}
Rhombus() {};
};
void Figure::Print() const
{
cout << " My figure type is" << type
<< " My area is " << &Figure::area;
}
int main()
{
Rectangle rectangle;
rectangle.area(5.4,6.2);
rectangle.Print();
Triangle triangle(4.5,5.3);
triangle.Print();
Circle circle(6.6, 8.8);
circle.Print();
Rhombus rhombus(3.4,5.4);
rhombus.Print();
}
You are getting 1 because a valid function pointer is treated as true.
You should call the function area like Figure::area(x, y) instead of getting the address of the function area like &Figure::area.
it's simple. really.
When you do
rectangle.area(x, y);
you just return the value you obtain from the variables that you passed in. You never assign a value to the x and y of the actual rectangle. So when you do print the area of the rectangle you use its real x and y, which do not have a value assigned to them, hence resulting in a 1. it's the same for the other shapes.
I am trying to figure out how to find the axis of class Square's axis as shown below? But I've been trying for hours and still did not managed to solve it. Can someone with their high level expertise show me the ropes to do it? Because both center function call and axis function call in main() does call the same x() and y(), hence brought me to a state of confusion. I know the inheritance of square from circle is weird. But it is what my school wants. Note: Main() CANNOT be modified! Thanks!
Output:
Square::axis test failed
8.87627 0.284967
3.82567 0.958537
Tests passed: 50%
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <cmath>
class Object
{
public:
private:
float d;
public:
Object(float n) : d(n){}
Object(){}
float depth() const
{
return d;
}
struct PointType
{
float x2;
float y2;
PointType( float x1, float y1) :x2(x1),y2(y1){}
PointType(){}
float x()
{
return x2;
}
float y()
{
return y2;
}
PointType center()
{
return *this;
}
};
struct VectorType
{
float tx;
float ty;
VectorType( float tx1, float ty1) :tx(tx1),ty(ty1){}
VectorType( ){}
};
virtual ~Object()
{}
};
class Point :public Object
{
private:
PointType mpoint;
public:
Point(const PointType& pt, float& y1) :Object(y1), mpoint(pt) {}
Point(const PointType& pt):mpoint(pt){}
Point(){}
Point center() const
{
return *this;
}
float x()
{
return mpoint.x2;
}
float y()
{
return mpoint.y2;
}
virtual ~Point(){}
};
class Circle : public Point
{
private:
Object::PointType m_pt;
float r;
public:
Circle(const PointType pts, float rad, float dep)
: Point(m_pt,dep),m_pt(pts),r(rad) {}
Circle(const PointType pts, float rad):m_pt(pts),r(rad){}
Circle(){}
float radius() const
{
return r;
}
Circle center() const
{
return *this;
};
float x()
{
return m_pt.x2;
}
float y()
{
return m_pt.y2;
}
};
class Square: public Circle
{
private:
Object::PointType s_pt;
Object::VectorType v_pt;
float a=getRadius();
public:
Square(const PointType spts,const VectorType vpts,float depth) :
Circle(spts,a,depth),s_pt(spts),v_pt(vpts){}
Square(const Object::PointType& spts, const VectorType vpts):s_pt(spts),v_pt(vpts){}
Square axis() const
{
return Square(s_pt,v_pt,getRadius());
}
Square center() const
{
return *this;
}
float radius() const
{
return a;
}
float getRadius() const
{
float rad= sqrt(v_pt.tx * v_pt.tx + v_pt.ty * v_pt.ty);
return rad;
}
float x() const
{
return s_pt.x2;
// v_pt.tx/radius();
}
float y() const
{
return s_pt.y2;
// v_pt.ty/radius();
}
};
const float EPSILON = 1e-5f;
bool is_near(float x, float y)
{
return std::abs(x - y) < EPSILON;
}
float frand()
{
return 10.0f * float(rand()) / float(RAND_MAX);
}
int main()
{
srand(unsigned(time(0)));
int count = 0;
int max_count = 0;
float x = frand();
float y = frand();
float sx = frand();
float sy = frand();
float depth = frand();
Square square(Square::PointType(x, y), Square::VectorType(sx, sy), depth);
if (is_near(square.center().x(), x) &&
is_near(square.center().y(), y))
{
++count;
}
else
{
std::cout << " - Square::center test failed" << std::endl;
}
++max_count;
float radius = std::sqrt(sx * sx + sy * sy);
if (is_near(square.axis().x(), sx / radius) &&
is_near(square.axis().y(), sy / radius))
{
++count;
}
else
{
std::cout << " - Square::axis test failed" << std::endl;
}
++max_count;
std::cout << square.axis().x()<< " " << sx / radius<<std::endl;
std::cout << square.axis().y()<< " " << sy / radius<<std::endl;
int result = static_cast<int>(
100.0f * static_cast<float>(count) / static_cast<float>(max_count) + 0.5f
);
std::cout << "Tests passed: " << result << "%" << std::endl;
return result;
}
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);
};
Using inheritance classes, I am looking to calculate the area of 2d shapes and area and volume of 3d shapes. I am now need to access the array determine the shape and then determine whether to calculate the area or the volume of the shape. The end goal is to loop through and provide output saying the name of the shape the area and/or the volume. How do I access the object names of the array? Thanks
/---------------------------------------------------------
#ifndef SHAPE_H
#define SHAPE_H
const double PI = 3.14159265359;
//Base Class---------------------------------------------
Class Shape {
protected:
//Dimensions
int dimensions;
double area;
double volume;
public:
//Default Constructor
Shape();
//Destructor
~Shape();
//Get Dimension function
double getDimensions();
//virtual function
virtual double getArea();
virtual double getVolume();
};
//Shape Type-----------------------------------------------
class TwoDimensionalShape : public Shape {
protected:
double d1, d2;
public:
double get_d1() { return d1; }
double get_d2() { return d2; }
double set_d1(double x) { d1 = x; }
double set_d2(double x) { d2 = x; }
};
class ThreeDimensionalshape : public Shape {
protected:
double d1, d2, d3;
public:
double get_d1() { return d1; }
double get_d2() { return d2; }
double get_d3() { return d3; }
double set_d1(double x) { d1 = x; }
double set_d2(double x) { d2 = x; }
double set_d3(double x) { d3 = x; }
};
//two dimensionals Shape classes-------------------------
class Circle : public TwoDimensionalShape {
public:
Circle(); //default constructor
Circle( double r); //regular constructor
double getArea(); //get area function
};
class Square : public TwoDimensionalShape {
public:
Square();
Square(double dim);
double getArea();
};
class Triangle : public TwoDimensionalShape {
public:
Triangle();
Triangle(double dim, double dim2);
double getArea();
};
//three dimensional shape classes-------------------------
class Sphere : public ThreeDimensionalshape {
public:
Sphere();
Sphere(double dim);
double getArea();
double getVolume();
};
class Cube : public ThreeDimensionalshape{
public:
Cube();
Cube(double dim);
double getArea();
double getVolume();
};
class Tetrahedron : public ThreeDimensionalshape{
public:
Tetrahedron();
Tetrahedron(double dim);
double getArea();
double getVolume();
};
--
//---------------------------------------------------------
#include <stdlib.h>
#include <cmath.h>
#include "shape.h" //header file
using namespace std;
//----------------------------------------------
//Default constructor
Shape::Shape() : dimensions(0), area(0), volume(0) { }
//Regular constructor
Shape::Shape(int d) : {
dimensions = d;
}
//Function getDimensions
double Shape::getDimensions() {
return dimensions;
}
//Two dimensional shapes-----------------------------------
//Default constructor--------------------
Circle::Circle() {
d1 = 1 ;
}
//Regular constructor--------------------
Circle::Circle( double r ) {
d1 = r;
}
//Circle area
double Circle::getArea() {
area = PI * pow( d1, 2 );
return area;
}
//Default constructor--------------------
Square::Square() {
d1 = 1 ;
d2 = 1;
}
//Regular constructor--------------------
Square::Square( double dim ){
d1 = dim;
d2 = dim;
}
//Square area
double Square::getArea(){
area = pow( d1, 2 );
return area;
}
//Default constructor--------------------
Triangle::Triangle(){
d1 = 1;
d2 = 1;
}
//Regular constructor--------------------
Triangle::Triangle(double dim, double dim2){
d1 = dim;
d2 = dim2;
}
//Triangle area
double Triangle::getArea(){
area = (d1 * d2) / 2;
}
//Three dimensional shapes-----------------------------------
//Default constructor---------------------
Sphere::Sphere(){
d1 = 1;
d2 = 1;
d3 = 1;
}
//Regular constructor---------------------
Sphere::Sphere(double dim) : {
d1 = dim;
d2 = dim;
d3 = dim;
}
//Sphere area
double Sphere::getArea(){
area = 4 * PI * pow( d1, 2 );
return area;
}
//Sphere volume
double Sphere::getVolume(){
volume = (4/3) * PI * pow( d1, 3 );
return volume;
}
//Default constructor---------------------
Cube::Cube(){
d1 = 1;
d2 = 1;
d3 = 1;
}
//Regular constructor---------------------
Cube::Cube(double dim){
d1 = dim;
d2 = dim;
d3 = dim;
}
//Cube area
double Cube::getArea(){
area = pow( d1, 2 );
return area;
}
//Cube Volume
double Cube::getVolume(){
volume = pow( d1, 3 );
return volume;
}
//Default constructor---------------------
Tetrahedron::Tetrahedron(){
d1 = 1;
d2 = 1;
d3 = 1;
}
//Regular constructor---------------------
Tetrahedron::Tetrahedron(double dim){
d1 = dim;
d2 = dim;
d3 = dim;
}
//tetrahedron area
double Tetrahedron::getArea(){
area = sqrt(3) * pow( d1, 2);
return area;
}
//tetrahedron volume
double Tetrahedron::getVolume(){
volume = pow(d1, 3) / (6 * sqrt(2));
return volume;
}
--
/---------------------------------------------------------
#include <stdlib.h>
#include <cmath.h>
#include "shape.h" //header file
using namespace std;
int main() {
//Pointer Array--------------------------------------------
Shape* arr[6];
//Assign Shape Dimensions and to Array
Circle cir(2); //declares value for circle ~ cir is var name
arr[0] = ○ //assigns cir var to array position 0
Square sqr(3);
arr[1] = &sqr;
Triangle tri(4, 2);
arr[2] = &tri;
Sphere sph(5);
arr[3] = &sph;
Cube cb(6);
arr[4] = &cb;
Tetrahedron trhd(7);
arr[5] = &trhd;
//Loop each index of array and perform calculation
for (int i = 0; i < 6; ++i)
{
cout << ""
}
}
I suggest to add something like toString method to your Shape class and try to override it in your inherited classes like :
Class Shape{
...
public:
std::string toString();
...
}
Implement and override it in the subclasses:
std::string Shape::toString()
{
return "This is a simple shape";
}
std::string Cube::toString()
{
return "Cube";
}
...
through the power of polymorphism, you will get the object name in your for loop just by calling:
cout << arr[i].toString() << ...
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
{
//...
};