Я написал класс Fraction для работы с объектами Fraction, перегрузкой и т.п., и мне нужно отделить реализацию от определений методов, но я получаю ошибку переопределения, когда дело доходит до конструкторов класс Fraction.

Фрагмент кода из Fraction.h

class Fraction
{
private:
   int calcGCD(int n1, int n2) const;
   int compare(const Fraction& fraction) const;
   int m_numerator;
   int m_denominator;
public:
   Fraction(int numerator = 0, int denominator = 1) : m_numerator(numerator), m_denominator(denominator);
   Fraction(const Fraction& fraction) : m_numerator(fraction.numerator()), m_denominator(fraction.denominator());
   Fraction(const Fraction& orig);
};

Фрагмент кода из Fraction.cpp

#include "Fraction.h"

Fraction::Fraction(int numerator, int denominator) 
   : m_numerator(numerator), m_denominator(denominator)
{}

Fraction::Fraction(const Fraction& fraction)
   : m_numerator(fraction.numerator()), m_denominator(fraction.denominator())
{}

Это приводит к следующим ошибкам:

Fraction.h:26:5: error: 'Fraction::Fraction(const Fraction&)' cannot be overloaded with 'Fraction::Fraction(const Fraction&)'
Fraction.h:25:5: note: previous declaration 'Fraction::Fraction(const Fraction&)'
Fraction.h:24:105: error: expected '{' at end of input

Далее следуют некоторые другие, которые, я думаю, являются лишь каскадным эффектом одной или двух основных ошибок. Но я могу опубликовать их, если это действительно необходимо.

Я думаю, это как-то связано с тем, как я объявляю конструктор в файле .cpp, потому что я знаю, что некоторые вещи не переносятся, например, модификаторы доступа, static и т. Д.

Извините, если это глупая ошибка, я новичок в C ++ и нигде не могу найти ответ.

1
katie1245 29 Июл 2020 в 22:52

2 ответа

Лучший ответ

В опубликованном вами коде есть несколько ошибок.

Во-первых, конструктор копирования объявляется дважды в заголовочном файле. Оба эти объявления одинаковы, потому что их параметры имеют одинаковый тип.

Fraction(const Fraction& fraction);
Fraction(const Fraction& orig);

Во-вторых, конструкторы определены дважды: один раз в заголовочном файле, один раз в исходном файле. Там может быть только одно определение. Вы можете выбрать, какой из них оставить. Я обычно предпочитаю определять их в исходном файле (.cpp), чтобы скрыть детали реализации.

Наконец, если вы сохраните определение в заголовочном файле, пара скобок будет отсутствовать. Допустимая реализация в заголовочном файле будет выглядеть так:

class Fraction {      
private:
    ...
    int m_numerator;
    int m_denominator;
public:
    Fraction(int numerator = 0, int denominator = 1) : m_numerator(numerator), m_denominator(denominator) {}
    Fraction(const Fraction &fraction) : m_numerator(fraction.numerator()), m_denominator(fraction.denominator()) {}
    ...
}
2
guiguimo 29 Июл 2020 в 20:11

Вы объявили конструктор копирования дважды.

Fraction(const Fraction& fraction) ....
Fraction(const Fraction& orig);

Посмотри на подпись. Они одинаковы, что невозможно в C ++.

Вы, вероятно, имели в виду Fraction.h

Fraction(const Fraction &fraction); // only one

И в Fraction.cpp

Fraction::Fraction(const Fraction& fraction)
   : m_numerator(fraction.numerator())
   , m_denominator(fraction.denominator())
{}

Короче говоря, вам нужно удалить один из них.

5
JeJo 29 Июл 2020 в 19:54