Reputation: 1065
I'm relatively new to C++ and have been trying to troubleshoot this problem for awhile now, but can't figure this out. I have 2 classes, one called Polygon
and one called Rectangle
. Rectangle
is a child class of Polygon
. Polygon
contains a std::vector<Points>
called _points
.
I would like my Rectangle
constructor to add some Points to _points
based on the constructor arguments. That sounded simple enough. However, when I add Points to _points
, they seem to get lost outside of the constructor. When I check the size of _points
inside the constructor, it gives the right value. However, when I check it back in the main program, right after constructing the Rectangle
, it is 0. I think there is something going on under the hood I don't know about. Any ideas on what could be wrong?
Here's some snippets of code I think may help
Polygon.cpp
// This is just for reference, there are a few other classes involved
// but I don't think they should effect this.
Polygon::Polygon()
: Object()
, _lastColor(0,0,0)
, _lastDotColor(.5, .5, .5)
{
_points = vector<Point>();
_colors = vector<RGB>();
_dotColors = vector<RGB>();
_numDotSections = -1;
}
Rectangle.cpp
Rectangle::Rectangle(Point p1, Point p2, RGB lineColor, double dotSeg, RGB dotColor) : Polygon(){
_points.push_back(p1);
// Prints out 1
std::cout << "Point size: " << getPoints() << std::endl;
}
Driver.cpp
Rectangle playerPolygon = Rectangle(Point(1,1,-.75), Point(-1,-1,-.75), RGB(1,1,1));
// Prints 0
cout << "Number of points (Rectangle): " << playerPolygon.getPoints() << endl;
Edit1: Per request, here's the majority of the text for Polygon.cpp
// File imports
#include <GL/glut.h>
#include <iostream>
#include <math.h>
#include "Polygon.h"
using namespace std;
/**
* Default constructor for Polygon. Uses initializer lists
* to setup the different attributes
*/
Polygon::Polygon()
: _lastColor(0,0,0)
, _lastDotColor(.5, .5, .5)
, _numDotSections(-1)
{
}
/**
* Transforms the points of the polygon and draws it on the screen
*
* @param currentWorld a reference to the world the object is in
*/
void Polygon::draw(World* currentWorld){
// Some long and overly complicated method that should not apply here
}
/**
* Adds a point to the polygon
*
* @param point the point to be added
* @param color the color to start at this point
* @param dotColor the dotted line color to start at this point
*/
void Polygon::addPoint(Point point, RGB color, RGB dotColor){
// Add the values to the lists
_points.push_back(point);
_colors.push_back(color);
_dotColors.push_back(dotColor);
// Update the last colors
_lastColor = color;
_lastDotColor = dotColor;
}
/**
* Adds a point to the polygon
*
* @param point the point to be added
* @param color the color to start at this point
*/
void Polygon::addPoint(Point point, RGB color){
// Add the point using the last dotted line color
addPoint(point, color, _lastDotColor);
}
/**
* Adds a point to the polygon
*
* @param point the point to be added
*/
void Polygon::addPoint(Point point){
// Add the point using the last line and dotted line color
addPoint(point, _lastColor, _lastDotColor);
}
/**
* Set the color of the current line
*
* @param color the color of the line to be added
*/
void Polygon::setColor(RGB color){
// Add the color to the list
_colors.back() = color;
// Update the last used color
_lastColor = color;
}
/**
* Set the dotted line color of the current line
*
* @param color the dotted line color to be added
*/
void Polygon::setDotColor(RGB color){
// Add the dotted line color to the list
_dotColors.back() = color;
// Update the last used dotted line color
_lastDotColor = color;
}
/**
* Sets the number of dotted sections for the current shape
*
* @param number the number of dotted sections
*/
void Polygon::setDotSections(int number){
_numDotSections = number;
}
// I just put this in to see if the issue was copying, but this text is never output
// so I don't believe it's being called
Polygon::Polygon(const Polygon& rhs){
std::cout << "Polygon copied" << std::endl;
std::cout << "RHS: " << rhs._points.size() << " LHS: " << getPoints() << std::endl;
}
int Polygon::getPoints(){
return _points.size();
}
Upvotes: 2
Views: 612
Reputation: 1065
After sleeping on it, I figured it out! Being used to Java, I had made what I thought were overloaded constructors:
Rectangle::Rectangle(Point p1, Point p2, RGB lineColor, double dotSeg, RGB dotColor) : Polygon(){
// Add some points here
}
Rectangle::Rectangle(Point p1, Point p2){
// Supposed to call the first constructor
Rectangle(p1, p2, RGB(), -1, RGB());
}
Rectangle::Rectangle(Point p1, Point p2, RGB lineColor){
// Supposed to call the first constructor
Rectangle(p1, p2, lineColor, -1, lineColor);
}
But then I tried using the main constructor in my program and it worked! After doing a bit of research, it turns out that constructors cannot be overloaded like this. When a constructor other than the original one is called, it creates a new Rectangle with the points, then destructs it right away because it's not set equal to anything and returns a new rectangle without the points.
I found the easiest way around this is to use default parameters, so I have the same functionality
Rectangle(Point p1, Point p2, RGB lineColor = RGB(), double dotSeg = -1, RGB dotColor = RGB());
I suppose this would have been caught if I put the entire code in there right away, but thanks for all the help and suggestions!
Upvotes: 1
Reputation: 106609
Rectangle playerPolygon = Rectangle(...);
You're invoking the copy constructor here. Did you write a copy constructor? Is it copying _points
? If not, that's a bug; and there's really no need to force another copy constructor call in any case. Why not just
Rectangle playerPolygon(...);
? (But do watch out for the vexing parse...)
Upvotes: 1
Reputation: 58685
A few hints that don't answer your question, but nonetheless:
Rectangle
from Polygon
. Unless you plan on taking advantage of polymorphism with the two types then it's not necessary and can even lead to incorrect code. The same holds for deriving Polygon
from Object
._points = vector<Point>();
in the default Polygon
constructor is redundant. Also, the call to the default constructor of Object()
in that same Polygon
constructor is redundant.Upvotes: 0
Reputation: 283783
A wild guess: Rectangle
inherits from Polygon
, and the Rectangle
class declares a second member variable named _points
that hides the base class version. Rectangle
's constructor then adds some elements to Rectangle::_points
, and some other function later checks the size of Polygon::_points
and finds none.
If this is the case, just take away the declaration of _points
in Rectangle
. It needs to use the base class version, either directly if Polygon::_points
is accessible (public or protected), or via accessor functions.
Upvotes: 0
Reputation: 374
I don't see a reason. But I strongly suggest that you delete some lines in the constructors for copying objects. Also, the default constructor is not necessary to be in the constructor initialization list.
// This is just for reference, there are a few other classes involved
// but I don't think they should effect this.
Polygon::Polygon()
: _lastColor(0,0,0)
, _lastDotColor(.5, .5, .5)
, _numDotSections(-1)
{
}
How do you implement getPoints()?
Upvotes: 1