user1017413
user1017413

Reputation: 2183

C++: Unresolved externals driving me nuts

I'm taking a class on C++ and this is driving me berserk. The funnest part is that no guide seems to tell me exactly what to do and no question seems to address the problem here. It's probably due in part to the issue of multiple C++ compilers. I'm using Visual Studio 2010 and I'm just trying to build a class with operator overloading. I have my header, class, main, etc:

//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

And the class:

#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));
    }

The getter functions are what you'd expect and don't error out, but the constructor and overloaded methods give me the unresolved external. I can't even remember how much stuff I've tried in the methods and the header. I've seen a dozen or so guides and examples, and none of them have worked. I did get this to compile once with the + operand as a friend function, but it needs to be a member function for the assignment, and moving it to a member function somehow managed to break all of the above. I'm going nuts here. It won't resolve those methods no matter what I do!

The main method invokes all this in the standard fashion and includes the Rational.h file. All files are in the same directory.

Upvotes: 1

Views: 398

Answers (3)

sehe
sehe

Reputation: 393527

You are clearly learning things. I took the time to fix a number of 'minor' issues that will really be hampering your progress; I hope my stenographic explanations will put you on the right path.

  • You are redefining the class in a cpp file; this is not proper C++ (declare the class in the header, define the implementation in the cpp):

  • You fail to return values in non void methods

  • You fail to return the result of assignment by reference (only breaks expectations - but returning by reference is recommend and idiomatic)
  • += fails to update *this and return the same

I also demonstrated initializer lists and implemented += in terms 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()
{
}

Upvotes: 3

Rob Kennedy
Rob Kennedy

Reputation: 163317

The code you've shown includes two definitions of Rational. If you have Rational once without inline implementations to the methods, the methods need to be defined elsewhere, but separately, not all grouped inside another class structure. After including the header, which looks good, put the implementation of each method on its own, like so:

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

What you've shown would not lead to "unresolved external" errors, though. It should give you "multiple class definition" errors. Unless you've completely neglected to include the second Rational file in your project. Then "unresolved external" is indeed correct because you haven't provided proper definitions for the functions in that class.

Upvotes: 2

rerun
rerun

Reputation: 25505

You are declaring the class twice.

Your header should look like it does but when you define the function they should not be wrapped inside a class block.

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();
};

Now define it in your .cpp.

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

Also remember you can define functions inline.

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();
};

Upvotes: 2

Related Questions