0

I got a class WayPoint that contains a pair of doubles and a name. I got a class WayPointContainer that contains a vector of Waypoints.

WayPointContainer got a method to add a WayPoint to its vector and a Print Method to show the WayPoints inside the vector. I implemented both but dont know how to check if it works. My Print Method does not print any WayPointName. So either my Add method or my Print method is wrong.

So as soon as i call the Add method c1->Add(*p1) of WayPointContainer the programm stops. i tryd different version using insert() of vector with iterator. I also tryd printing the capacity but every method just leads to a programm stop so i guess something with initialisation is wrong ? I got the header files from my prof so i am hoping they are correct. And since he doesnt answer me i try it here.

I tryd debugging it but i find the information given by debugging really hard to read and use. I also tryd different implementations of the methods but it was always the same result.

WayPoint.h

#ifndef WAYPOINT_H_
#define WAYPOINT_H_
#include <iostream>

namespace HHN {

class WayPoint {
private:
    std::string name{ "" };
    std::pair<double, double> coords{ 0.0, 0.0 };
public:
    WayPoint();
    virtual ~WayPoint();
    WayPoint(const WayPoint& orig);
    WayPoint(const std::string& xName, double xCoord, double yCoord);

    WayPoint& operator=(const WayPoint& rhs);

    std::string Name() const;
    double first() const;
    double second() const;
};

} /* namespace HHN */

#endif /* WAYPOINT_H_ */

WayPoint.cpp

#include "WayPoint.h"

namespace HHN {

WayPoint::WayPoint() {}

WayPoint::~WayPoint() {}

WayPoint::WayPoint(const WayPoint& orig) {}

WayPoint::WayPoint(const std::string& xName, double xCoord, double yCoord) {
    this->name = xName;
    this->coords.first = xCoord;
    this->coords.second = yCoord;
}

WayPoint& WayPoint::operator =(const WayPoint& rhs) {
    if (this == &rhs) {
        return *this;
    }
    else {
        this->coords.first = rhs.first();
        this->coords.second = rhs.second();
        this->name = rhs.Name();
    }
    return *this;
}

std::string WayPoint::Name() const {
    return name;
}

double WayPoint::first() const {
    return this->coords.first;
}

double WayPoint::second() const {
    return this->coords.second;
}

} /* namespace HHN */

WayPointContainer.h

#include <vector>
#include <iostream>
#include "WayPoint.h"

#ifndef WAYPOINTCONTAINER_H_
#define WAYPOINTCONTAINER_H_

class WayPointContainer {
private:
    std::vector<HHN::WayPoint>* pContainer{nullptr};
public:
    WayPointContainer();
    WayPointContainer(const WayPointContainer& orig);
    virtual ~WayPointContainer();

    WayPointContainer& operator=(const WayPointContainer& rhs);
    HHN::WayPoint& operator[](int idx) const;

    void Add(const HHN::WayPoint& arg);
    int Size() const;
    void Print() const;
};

#endif /* WAYPOINTCONTAINER_H_ */

WayPointContainer.cpp

#include "WayPointContainer.h"
#include <vector>
#include <iostream>
using namespace std;

WayPointContainer::WayPointContainer() {
    pContainer = new std::vector<HHN::WayPoint>;
}

WayPointContainer::WayPointContainer(const WayPointContainer& orig) {
    pContainer = orig.pContainer;
}

WayPointContainer::~WayPointContainer() {
    delete[] pContainer;
}

WayPointContainer& WayPointContainer::operator =(const WayPointContainer& rhs) {
    if (this == &rhs) {
            return *this;
        }
    else {
        pContainer = rhs.pContainer;
    }
    return *this;
}

HHN::WayPoint& WayPointContainer::operator [](int idx) const {
    return (*pContainer)[idx];
}

void WayPointContainer::Add(const HHN::WayPoint& arg) {
    this->pContainer->push_back(arg);
}

int WayPointContainer::Size() const {
    return pContainer->size();
}

void WayPointContainer::Print() const {
    for (auto waypoint = pContainer->begin(); waypoint != pContainer->end(); ++waypoint) {
            auto tmp = waypoint->Name();
            cout << tmp << " <- Name" << "\n";
        }
}

Main.cpp

#include <iostream>
using namespace std;
#include "WayPoint.h"
#include "WayPointContainer.h"

int main() {
    cout << "!!!Hello World!!!" << endl;

    HHN::WayPoint *p1 = new HHN::WayPoint("nameOfP1",1.5,1.5);  // works
    HHN::WayPoint *p2(p1);                              // works

    WayPointContainer *c1 = new WayPointContainer();    // works
    WayPointContainer *c2(c1);                          // works
    WayPointContainer *c3 = new WayPointContainer();

    c1->Add(*p1);
    c1->Print();

    cout << " Punkt1: " << p1->Name() << " "<< p1->first() << " " << p1->second() << "\n";

    cout << "!!!Hello World out!!!" << endl;
    return 0;
}

The console output i am getting is :

!!!Hello World!!!
 <- Name
 Punkt1: nameOfP1 1.5 1.5
!!!Hello World out!!!

but i am expecting

!!!Hello World!!!
 nameOfP1 <- Name
 Punkt1: nameOfP1 1.5 1.5
!!!Hello World out!!!

(This is actually a task from my prof to implement the header files given. And since he ignored my mails so far i am trying it here. I am pretty sure this is something very small and probably obvious to fix but i am very much a beginner of C++ and struggle alot. I am sitting already days on that implementation.)

Saturas
  • 535
  • 1
  • 4
  • 12
  • 2
    You should take a look at [What is a debugger and how can it help me diagnose problems?](https://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems). – Jesper Juhl Apr 22 '19 at 10:44
  • 3
    The `pContainer` member variable being a pointer to a std::vector is not a good design. This has lead to several bugs. Your copy constructor and copy-assignment operator will make both containers point to the same std::vector. I don't think you want changes of one container to appear in both. This will also lead to double delete errors when they're destroyed. You destructor uses `delete[]` when it should just be `delete`. My advice is to stop using pointers and `new`. They aren't needed anywhere in this code and are just causing bugs and memory leaks. – Blastfurnace Apr 22 '19 at 11:11
  • Just a small update. I printed out where the pointers point to (hex values) to compare the vectors of the objects and i realized that my copy constructor of WayPointContainer.cpp was wrong. With this implementation it works: ```pContainer = new std::vector(*orig.pContainer);``` – Saturas Apr 24 '19 at 07:43

1 Answers1

2

You are inserting a copy of WayPoint into the container, but you missed implementing a copy constructor.

void WayPointContainer::Add(const HHN::WayPoint& arg) {
// push_pack do copy object
    this->pContainer->push_back(arg);
}
WayPoint::WayPoint(const WayPoint& orig) {}

Try to implement copy constructor.

WayPoint::WayPoint(const WayPoint& orig) {
    name = orig.name;
    coords.first = orig.coords.first;
    coords.second = orig.coords.second;
}
  • You are right thanks i completely missed that. Now i only have to get the destructor part right because if i delete pContainer of C1 while C2 = C1 the pContainer of C2 will also be deleted. – Saturas Apr 22 '19 at 12:09