0

I read several similar posts, and I either did not understand what they had to offer, or they didn't seem to apply. I'm new here and trying my best to follow the rules.

We're learning c++ in the last 2 weeks of the course and its on the final in 40 hours :) , so I am a beginner. I am familiar with C.

Here is the part of the assignment that is relevant:

Part 1 [20 points]
Reading material:
Copy constructor: https://www.geeksforgeeks.org/copy-constructor-in-cpp/
References (the & symbol): https://www.geeksforgeeks.org/references-in-c/
------------------------------------------------------------------------------------------------------
Write a class Point representing a point in 2d.
The class will have the following public methods:
// constructor - sets the coordinates to be x,y
Point( int x, int y)
// copy constructor - creates a new point with the same
coordinates
Point(Point &copy)
// getters
int getX()
int getY()
// setters
void setX()
void setY()
// prints to screen the coordinates in the format (x,y)
void print()

My Implementation of:

Point.hpp

#include <iostream>

using namespace std;

class Point { 
   private: 
   int x, y; 

public: 
    // Parameterized Constructor 
    Point(int x1, int y1); 

    ~Point();

    Point (const Point &p2);

    int getX();

    int getY(); 


    void setX(int x2);


    void setY(int y2);

    void print();
};

Point.cpp

#include "Point.hpp"

Point::Point(int x1, int y1)
    { 
        x = x1; 
        y = y1; 
    } 
Point::Point (const Point &p2)
    {
        x = p2.x;
        y = p2.y;
    }

int Point::getX()
    { 
        return x; 
    } 

int Point::getY()
    { 
        return y; 
    } 

void Point::setX(int x2)
    {
      x = x2;
    }

void Point::setY(int y2)
    {
      y = y2;
    }

void Point::print()
    {
        cout << "(" << x << "," << y << ")";
    }

The part of the Question I am stuck on

Part 2 [20 points]
Reading material:
Abstract classes and pure virtual methods:
https://www.geeksforgeeks.org/pure-virtual-functions-and-abstract-classes/
---------------------------------------------------------------------------------------------------
Write an abstract class GeometricShape representing an abstract geometric
shape. The class will have the following public methods:
// Constructor: gets a coordinate. The purpose of the
coordinate depends on the specific shape
GeometricShape(Point coord)
// returns the area of the shape
// returns 0 as default. To be implemented in each
concrete shape
virtual float getArea() { return 0 ; }
// returns the perimeter of the shape
// returns 0 as default. To be implemented in each
concrete shape
virtual float getPerimeter() { return 0 ; }
// virtual method. To be implemented in each concrete
method
virtual void print() = 0 ;

My Implementation of:

GeometricShape.hpp

#include <iostream>
#include "Point.hpp"

using namespace std;

class GeometricShape { 

private:
    Point point;

public: 
    // Parameterized Constructor 
    GeometricShape(Point coord); 

    virtual float getArea();

    virtual float getPerimeter(); 

    virtual void print() = 0;
};

GeometricShape.cpp (this is what wont compile)

#include <iostream>
#include "GeometricShape.hpp"


GeometricShape::GeometricShape(Point coord)

{

Point p = new Point(coord.getX(),coord.getY());


}

int main()
{
  return 0;
}

Error message when compiled on Linux Ubunto 18.04.3 (university lab remotely accessed, assignments required to compile on linux in the lab)

Error message:

gsg27@csil-cpu2:~/sfuhome/cmpt-125/5$ g++ GeometricShape.cpp
GeometricShape.cpp: In constructor ‘GeometricShape::GeometricShape(Point)’:
GeometricShape.cpp:9:11: error: conversion from ‘Point*’ to non-scalar type ‘Point’ requested
 Point p = new Point(coord.getX(),coord.getY());
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  • 2
    If you're familiar with C, you understand pointers, right? So you know that `struct Point p = malloc(sizeof(struct Point));` wouldn't compile? How would you fix that in C? – Useless Dec 06 '19 at 00:15
  • 1
    I do indeed, thanks! – Useless Dec 06 '19 at 00:16
  • 1
    Why do you need dynamic allocation (`new`), in the first place? – Algirdas Preidžius Dec 06 '19 at 00:16
  • 1
    wild stab here, but maybe OP means to initialize the member variable `point` , instead of creating a new Point and doing nothing with it – M.M Dec 06 '19 at 00:17
  • The above being said, [Why should C++ programmers minimize use of 'new'?](https://stackoverflow.com/questions/6500313/why-should-c-programmers-minimize-use-of-new) – user4581301 Dec 06 '19 at 00:20
  • Thank you! After alot of back and forth and finally asking the prof, it turns out what @M.M mentioned is what i was missing! – big friendly giant Dec 06 '19 at 00:21
  • Unrelated: The implementation of `~Point();` is missing. Fortunately [the Rule of Zero](https://en.cppreference.com/w/cpp/language/rule_of_three) suggests that you don't need to define your own destructor at all. – user4581301 Dec 06 '19 at 00:23
  • `GeometricShape` could [benefit from a `virtual` destructor, though.](https://stackoverflow.com/questions/461203/when-to-use-virtual-destructors) – user4581301 Dec 06 '19 at 00:25
  • Yes i thought I did not need ~Point(); and a virtual destructor isnt needed in the context of this assignment, but I guess I will find out as I move on. Next part is making a Circle and Rectangle class using it. Thanks! – big friendly giant Dec 06 '19 at 00:27
  • I'm guessing posting my working solution is the correct thing to do once I have it? – big friendly giant Dec 06 '19 at 00:27
  • Feel free to self-answer so long as you explain what the problem was and how it was fixed so that future coders can learn from it. – user4581301 Dec 06 '19 at 05:05

2 Answers2

3

Your immediate problem is that the line

Point p = new Point(coord.getX(),coord.getY());

doesn't make sense. The new expression returns a pointer to a dynamically-allocated object. So, the code you wrote should be

Point *p = new Point(coord.getX(),coord.getY());

Except that you don't want a pointer, and you don't want a dynamically-allocated object: you're just trying to initialize a data member. So really your constructor should be

GeometricShape::GeometricShape(Point coord) : point(coord) {}

because you already have the data member GeometricShape::point and the Point class has a copy constructor. It would be more usual to write

GeometricShape::GeometricShape(Point const &coord) : point(coord) {}

because you don't need to make two copies of the original, but it's not a big deal here.

Useless
  • 64,155
  • 6
  • 88
  • 132
0

After taking in all of the help above and consulting my professor:

It should be implemented as follows, and is working correctly

#include <iostream>
#include "Point.hpp"

using namespace std;

class GeometricShape { 

private:
    Point point;
    float area;
    float perimeter;

public: 
    // Parameterized Constructor 
    GeometricShape(Point coord) :  point(coord.getX(), coord.getY())  // initialize the data field
    {
      area = 0;
      perimeter = 0;
    }

    virtual float getArea();

    virtual float getPerimeter(); 

    virtual void print() = 0;
}; 

Note, Because it is an abstract class, I found it less confusing as a beginner to make it all one file instead of separating it into a hpp and cpp file.