C ++: нерешенные внешние проблемы сводят меня с ума - PullRequest
1 голос
/ 28 октября 2011

Я учусь на C ++, и это сводит меня с ума. Самое забавное то, что ни один гид не говорит мне точно, что делать, и ни один вопрос, кажется, не решает проблему здесь. Вероятно, это отчасти связано с проблемой нескольких компиляторов C ++. Я использую Visual Studio 2010 и просто пытаюсь создать класс с перегрузкой операторов. У меня есть заголовок, класс, основной и т. Д .:

//File Rational.h
#ifndef RATIONAL_H
#define RATIONAL_H

class Rational
{
private:
    int numerator;
    int denominator;

public:
    Rational(int num = 0, int den = 1);
    Rational operator+(const Rational &);
    Rational operator=(const Rational &);
    Rational operator+=(const Rational &);
    int getNum();
    int getDenom();
};
#endif

И класс:

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

class Rational
{
private:
    int numerator;
    int denominator;

public:
    Rational(int num = 0, int den = 1)
    {
        numerator = num;
        denominator = den;
    }
    Rational operator+(const Rational &r)
    {
        return Rational(((numerator * r.denominator) + (r.numerator * denominator)), (denominator * r.denominator));
    }

    Rational operator=(const Rational &r)
    {
        denominator = r.denominator;
        numerator = r.numerator;
    }

    Rational operator+=(const Rational &r)
    {
        return Rational(((numerator * r.denominator) + (r.numerator * denominator)), (denominator * r.denominator));
    }

Функции getter - это то, что вы ожидаете и не ошибаетесь, но конструктор и перегруженные методы дают мне неразрешенный внешний вид. Я даже не могу вспомнить, сколько всего я пробовал в методах и заголовке. Я видел дюжину или около того руководств и примеров, и ни один из них не работал. Я получил его для компиляции один раз с операндом + в качестве функции-друга, но он должен быть функцией-членом для назначения, и перемещение его в функцию-член каким-то образом нарушило все вышеперечисленное. Я схожу с ума здесь. Эти методы не разрешат, что бы я ни делал!

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

Ответы [ 3 ]

3 голосов
/ 28 октября 2011

Вы ясно изучаете вещи. Я нашел время, чтобы решить ряд «мелких» проблем, которые действительно будут препятствовать вашему прогрессу; Я надеюсь, что мои стенографические объяснения приведут вас на правильный путь.

  • Вы переопределяете класс в файле cpp; это неправильно C ++ (объявите класс в заголовке, определите реализацию в cpp):

  • Вы не можете вернуть значения в недействительных методах

  • Вы не можете вернуть результат присвоения по ссылке (только нарушает ожидания - но возврат по ссылке рекомендуется и идиоматично)
  • += не удается обновить *this и вернуть тот же

Я также продемонстрировал списки инициализаторов и реализовал += в терминах op operator+

.

//File Rational.h
#ifndef RATIONAL_H
#define RATIONAL_H

class Rational
{
private:
    int numerator;
    int denominator;

public:
    Rational(int num = 0, int den = 1);
    Rational operator+(const Rational &) const;
    Rational& operator=(const Rational &);
    Rational& operator+=(const Rational &);
    int getNum();
    int getDenom();
};
#endif

main.cpp:

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

Rational::Rational(int num, int den)
    : numerator(num), denominator(den) // prefer initializer lists
{
}

Rational Rational::operator+(const Rational &r) const
{
    return Rational(
            ((numerator * r.denominator) + 
             (r.numerator * denominator)), 
            (denominator * r.denominator));
}

Rational& Rational::operator=(const Rational &r)
{
    denominator = r.denominator;
    numerator   = r.numerator;

    return *this; // ADDED
}

Rational& Rational::operator+=(const Rational &r)
{
    return *this = (*this) + r;
}

int main()
{
}
2 голосов
/ 28 октября 2011

Код, который вы показали, включает два определения Rational.Если у вас есть Rational один раз без встроенных реализаций методов, методы должны быть определены в другом месте, но отдельно , а не все сгруппированы внутри другой class структуры.После включения заголовка, который выглядит хорошо, поместите реализацию каждого метода по-своему, например:

Rational::Rational(int num = 0, int den = 1)
{
    numerator = num;
    denominator = den;
}

То, что вы показали, не приведет к "неразрешенным внешним" ошибкам.Это должно привести к ошибкам «множественного определения класса».Если вы полностью не забыли включить второй файл Rational в свой проект.Тогда «неразрешенное внешнее» действительно правильно, потому что вы не предоставили правильные определения для функций в этом классе.

2 голосов
/ 28 октября 2011

Вы объявляете класс дважды.

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

class Rational
{
private:
    int numerator;
    int denominator;

public:
    Rational(int num = 0, int den = 1);
    Rational operator+(const Rational &);
    Rational operator=(const Rational &);
    Rational operator+=(const Rational &);
    int getNum();
    int getDenom();
};

Теперь определите это в вашем .cpp.

Rational::Rational(int num , int den )
{
  //Stuff Goes hear 
}

Также помните, что вы можете определять встроенные функции.

class Rational
{
private:
    int numerator;
    int denominator;

public:
    Rational(int num = 0, int den = 1)
    {
     //Stuff Goes hear 
    }
    Rational operator+(const Rational &);
    Rational operator=(const Rational &);
    Rational operator+=(const Rational &);
    int getNum();
    int getDenom();
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...