Неопределенная ссылка на оператор << в унаследованном классе

0

Я пытаюсь перегрузить операторы << и >> для класса многоугольника и производного класса треугольника. Проблема в том, что мой компилятор возвращает следующую ошибку:

error: undefined reference to 'operator<<(std::ostream&, triangle const&)'

Я вполне уверен, что я определил вышеперечисленного оператора. У меня есть следующая строка в файле triangle.h:

std::ostream & operator << (std::ostream & os, triangle const&);

Эта проблема возникает специально для класса треугольников. Когда я удаляю строку, пытающуюся вывести треугольник, моя программа работает правильно. Нет проблемы с выдачей многоугольника. Что вызывает эту проблему и как ее исправить? Это проблема с моей иерархией включения?

Я думаю, что соответствующие файлы - main.cpp, triangle.h и triangle.cpp, но я включил полную копию моего кода ниже, если ошибка вызвана чем-то другим. Спасибо за вашу помощь и терпение.

main.cpp

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

using namespace std;

int main()
{
    triangle t (vertex (0, 0), vertex (5, 0), vertex (0, 5));
    triangle l (t);

    cout << l[0] << endl;
    cout << "L: " << l << endl; //not working

    polygon p;
    p.add (vertex (0,0));
    cout << "P: " << p << endl; //working
    return 0;
}

triangle.h

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

class triangle : public polygon
{
public:
    triangle(vertex = vertex(), vertex = vertex(), vertex = vertex());

    triangle(const triangle &);

    double area() const;

    vertex operator[](size_t i) const;

private:
    size_t size() const;
    void add(vertex iv);
    std::vector<vertex> v;
};

std::ostream & operator << (std::ostream & os, triangle const&);
std::istream & operator >> (std::istream & is, triangle & t);

triangle.cpp

#include "triangle.h"
#include <math.h>
#include <cassert>


triangle::triangle(vertex ta, vertex tb, vertex tc)
{
    v.push_back(ta);
    v.push_back(tb);
    v.push_back(tc);
}

triangle::triangle(const triangle & t)
{
    v=t.v;
}

double triangle::area() const
{
    double a=sqrt((v[0].x-v[1].x)*(v[0].x-v[1].x)+(v[0].y-v[1].y)*(v[0].y-v[1].y));
    double b=sqrt((v[1].x-v[2].x)*(v[1].x-v[2].x)+(v[1].y-v[2].y)*(v[1].y-v[2].y));
    double c=sqrt((v[2].x-v[0].x)*(v[2].x-v[0].x)+(v[2].y-v[0].y)*(v[2].y-v[0].y));
    double s=((a+b+c)/2);
    return sqrt(s*(s-a)*(s-b)*(s-c));
}

vertex triangle::operator[] (std::size_t i) const
{
    assert (i<3);
    return v[i];
}

inline std::ostream & operator << (std::ostream & os, triangle const & t)
{
    std::cout << "test" << std::endl;
    return os << t[0];
}

std::istream & operator >> (std::istream & is, triangle & t)
{
    vertex vx;
    for (size_t i = 0; i < 3; ++i)
    {
        is >> vx.x >> vx.y;
        //t.v.push_back(vx);
    }
    return is;
}

polygon.h

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

class polygon

{
    public:
    // pre:
    // post: empty polygon created
    polygon();

    // pre:
    // post: polygon created and initialized to given polygon source
    polygon(const polygon & source);

    // pre:
    // post: return number of vertices in this polygon
    std::size_t size() const;

    // pre: 0 <= i < size()
    // post: return vertex i in this polygon
    vertex operator[](size_t i) const;

    // pre:
    // post: vertex is added to this polygon
    void add(const vertex & v);

    private:

    std::vector<vertex> v;

};

std::ostream & operator << (std::ostream & os, const polygon & p);
std::istream & operator >> (std::istream & is, polygon & p);

polygon.cpp

#include <cassert>
#include "polygon.h"

polygon::polygon()
{
    v = std::vector<vertex> ();
}

polygon::polygon(const polygon & p)
{
    v = p.v;
}

std::size_t polygon::size() const
{
    return v.size();
}

vertex polygon::operator[] (std::size_t i) const
{
    assert(i < size());
    return v[i];
}

void polygon::add(const vertex & vx)
{
    v.push_back(vx);
}

std::ostream & operator << (std::ostream & os, const polygon & p)
{
    for (std::size_t i = 0; i < p.size(); ++i)
        os << p[i] << " ";
    return os;
}

std::istream & operator >> (std::istream & is, polygon & p)
{
    std::size_t n;
    vertex vx;

    is >> n;
    for (size_t i = 0; i < n; ++i)
    {
        is >> vx.x >> vx.y;
        p.add(vx);
    }
    return is;
}

vertex.h

#include <iostream>

struct vertex
{
    double x, y;

    vertex(double ix = 0.0, double iy = 0.0)
    {
        x = ix;
        y = iy;
    }
};

std::ostream & operator << (std::ostream & os, const vertex & v);

vertex.cpp

#include "vertex.h"

std::ostream & operator << (std::ostream & os, const vertex & v)
{
    os << "(" << v.x << ", " << v.y << ")";
    return os;
}
  • 1
    Ошибка «неопределенная ссылка» звучит так, как будто вы не ссылаетесь на triangle.o или triangle.obj (зависит от вашей платформы).
  • 0
    @Matt Да, я изначально использовал 'const triangle', но я отредактировал свой код, чтобы он точно соответствовал ошибке компилятора, чтобы посмотреть, решит ли это проблему. Обе версии в настоящее время не работают.
Показать ещё 1 комментарий
Теги:
class
inheritance
operator-overloading

1 ответ

2
Лучший ответ

Вот ваша проблема:

// triangle.cpp
inline std::ostream & operator << (std::ostream & os, triangle const & t)
^^^^^^

Внутренние функции должны быть определены во всех единицах перевода, которые их используют, и это определяется только одним. Либо удалите inline, либо переместите определение в заголовок, чтобы сделать его доступным в любом месте его использования.

  • 0
    +1 подтверждено. Я получил сообщение об ошибке OP перед внесением этого изменения и успешно скомпилировал после удаления inline .
  • 0
    Спасибо, это решило проблему. Странно то, что я добавил это «встроенное» как попытку исправить еще одну ошибку, связанную с этой функцией, но, кажется, все работает гладко, как только я ее удаляю.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню