Problems With Composition (Homework)

I'm have some troubles with a homework assignment for school. I've compared my file line-by-line to a classmates and cannot figure out why his compiles and mine doesn't. I'll try to keep this short, please let me know if I didn't provide enough information.

The assignment has us create a few Ship objects that have a Coordinate object. In the main file, I need to print out the coordinate and also compare them to see if a collision has taken place. Here are the files:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//Ship.h
#ifndef SHIP_H
#define SHIP_H

#include <iostream>
#include "Coordinate.h"

using namespace std;

class Ship
{
public:
    Ship (Coordinate, double, double, double);
    Coordinate get_location ();
    void update_location ();
private:
    Coordinate coord;
    double x_inertia, y_inertia, z_inertia;
};

#endif 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//Ship.cpp
#include <iostream>
#include "Coordinate.h"
#include "Ship.h"

using namespace std;

Ship::Ship (Coordinate c, double x_int, double y_int, double z_int)
    : coord (c), x_inertia (x_int), y_inertia (y_int), z_inertia (z_int)
{

}

Coordinate Ship::get_location ()
{
    return coord;
}

void Ship::update_location ()
{
    coord.setCoordinate (coord.get_x() + x_inertia, 
                         coord.get_y() + y_inertia,
                         coord.get_z() + z_inertia);
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//Coordinate.h
#ifndef COORDINATE_H
#define COORDINATE_H

#include <iostream>
using namespace std;

class Coordinate
{
    friend ostream &operator<< (ostream&, Coordinate&);
private:
    double x, y, z;
public:
    Coordinate (double x = 0.0, double y = 0.0, double z = 0.0);
    void set_coordinate (double, double, double);
    double get_x ();
    double get_y ();
    double get_z ();
    Coordinate operator+ (Coordinate&);
    Coordinate operator- (Coordinate&);
    bool operator== (Coordinate&);
    bool operator!= (Coordinate&);
};

#endif 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//Coordinate.cpp
#include "Coordinate.h"
#include <iostream>

using namespace std;

Coordinate::Coordinate (double x, double y, double z)
{
    set_coordinate (x, y, z);
    // header file will set coordinates to 0, 0, 0 if no values are
    // given in the  ructor
}

// code omitted to save room

ostream &operator<< (ostream &output, Coordinate &coord)
{
    output << "(" << coord.x << ", " << coord.y << ", " << coord.z << ")";
    return output;
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include "Coordinate.h"
#include "Ship.h"
#include <iostream>
using namespace std;

bool detectCollisions(Ship ships[], int number_of_ships);

int main()
{
    Ship ships[4] = 
    {
        Ship(Coordinate(0,0,0), 1, 1, 1),
        Ship(Coordinate(5,5,5), 0, 0, 0),
        Ship(Coordinate(8,8,8), -1, -1, -1),
        Ship(Coordinate(100,100,100), 0,0,0)
    };

// code omitted to save room

bool detect_collisions(Ship ships[], int number_of_ships)
{
    for (int i = 0; i < number_of_ships; ++i)
    {
        for (int j = 0; j < number_of_ships; ++j)
        {
            cout << ships[0].get_location();
        }
    }
}


(so much for keeping it short)

I realize that the detect_collisions in pa10.cpp isn't really doing anything but I'm not to that point yet. The problem lies here though when trying to use any of the overloaded operators in the Coordinate class. Trying to print out the ship's Coordinate throws an error.

pa10.cpp:49: error: no match for ‘operator<<’ in ‘std::cout << ships[0].Ship::get_location()'

Am I missing something? Why isn't it using the overloaded operator in the Coordinate class to print out the location? I wouldn't figure that I would have to make a friend function or a function in the Ship class. Another thing I don't understand is that I can print out Coordinate objects just fine if I throw something like "cout << coord" in Ship.cpp.

There are some parts where I need to compare the two Coordinates, which I have defined in the Coordinate class but again, it gives me an issue.

Any ideas?
Last edited on
Here operator<< is declared a private method:
1
2
3
4
5
6
7
8
class Coordinate
{
    friend ostream &operator<< (ostream&, Coordinate&);// will be a private method
private:
    double x, y, z;
public:
    Coordinate (double x = 0.0, double y = 0.0, double z = 0.0);
    void set_coordinate (double, double, double);

Maybe move that declaration down a few lines.
I've tried that, it gives me the same errors. I tried it again just know to make sure I wasn't crazy, but yeah... Same problems.
> Here operator<< is declared a private method:
No. It's a global function, you are just saying that that functions is a friend.

@OP:
You are trying to pass a temporary by non-const reference. You can't do that.
Either pass it by value or by const reference


However, you need to observe const correctness.
By instance
1
2
3
4
5
6
7
8
9
10
class Ship
{
public:
    Ship (Coordinate, double, double, double);
    Coordinate get_location () const;//you will not modify *this
    void update_location ();
private:
    Coordinate coord;
    double x_inertia, y_inertia, z_inertia;
};
We haven't covered this in class so pardon my confusion.

By adding the const at the end, I'm saying that the Coordinate I'm returning is a const? And without specifying the const at the end of the function means the Coordinate that I am returning is passed by value? I've only heard of these terms when objects or primitives are used as arguments. So I'm still a little unclear as to what you mean.

I did put a const at the end of the get_location function in both the header and cpp file, but it didn't change anything. I'm still getting the same error.
The get_location const qualifier doesn't have anything to do with the issue you're experiencing (make no mistake though, it should be const.)

The const correctness of this function, on the other hand:

ostream &operator<< (ostream&, Coordinate&);

is an issue.


If you make it: ostream&operator<<(ostream&, const Coordinate&); your problem with binding a temporary to a non-const reference will disappear. Don't forget to update all relevant code (such as the definition and any forward declarations.)
1
2
Coordinate Ship::get_location () const; //C++
Coordinate Ship_get_location (const Ship *this); //equivalent C 
It simply says, `this method will not modify the state of the object, so allow it to be executed in constant objects'
Kind of wishing it was something more difficult than that.

I added in the const into the ostream function and it worked first time. Thanks for the help. Apparently I need to go back and cover const and when to use them.

Thanks again!
UCD should really get a mascot, lol. Have you tried running in Visual Studio vs. g++ to see what happens? I had almost the same error you are having on PA09 when I ran it in g++, but my code ran fine and compiled perfectly when I ran it in Visual Studio.
Simply because VS has an extension that allows that.
But according to the standard is incorrect.
Have you tried running in Visual Studio vs. g++ to see what happens?


The code wouldn't compile in VC++.

Simply because VS has an extension that allows that.


No, it doesn't.
Topic archived. No new replies allowed.