0

following standards, I splitted class definition in two files, these are they

fraction.h

#ifndef FRACTION_H
#define FRACTION_H

#include <string>
#include <cmath>
#include <climits>
using std::string;
using std::log10;
using std::ceil;


class fraction
{
private:
    int __max_arr_len = (int)ceil(log10(__LONG_MAX__));
    long numerator;
    long denomenator;
    string convertion(long _num);

public:
    void reduce();
    inline void set_numerator(long _new);
    inline void set_denominator(long _new);
    inline long get_numerator();
    inline long get_denominator();
    inline double get_fraction();
    inline string get_str_fraction();
    fraction(long _num, long _den);
};

#endif // FRACTION_H

fraction.cpp

#include "fraction.h"

long gcd(long _f, long _s) {

    if (_f % _s == 0)

        return _s;

    return gcd(_s, _f % _s);
}

string fraction::convertion(long _num) {

    char *arr = new char[this->__max_arr_len];
    int ind = 0;

    while (_num > 0) {

        *(arr + ind++) = (char)(30 + _num % 10);
        _num /= 10;
    }

    for (auto iter = arr; iter < arr + this->__max_arr_len; ++iter) {

        char temp = *iter;
        *iter = *(arr + this->__max_arr_len - 1 - (iter - arr));
        *(arr + this->__max_arr_len - 1 - (iter - arr)) = temp;

    }

    return string(arr);
}

fraction::fraction(long _num, long _den)
{

    this->denomenator = _den;
    this->numerator = _num;

}

void fraction::reduce() {

    long _gcd = gcd(this->numerator, this->denomenator);

    this->denomenator /= _gcd;
    this->numerator /= _gcd;


}

inline void fraction::set_denominator(long _new) { this->denomenator = (_new != 0) ? _new : this->denomenator; }
inline void fraction::set_numerator(long _new) { this->numerator = _new; }
inline long fraction::get_denominator() { return this->denomenator; }
inline long fraction::get_numerator() { return this->numerator; }
inline double fraction::get_fraction() { return (double) this->numerator / this->denomenator; }
inline string fraction::get_str_fraction() { return convertion(this->numerator) + '/' + convertion(this->denomenator); }

The problem is, including header in my main.cpp still leaves unresolved reference, linker says there is no definition for class members.

I've seen many examples where this approach works, yet leaving me in wondering how, since no explicit reference to class.cpp has been present.

The question is more about how does linker knows which source file contains definition for a class that has a template in header.

Looks like I'm missing something, any suggestions?

Help much appreciated.

P.S. never tested it so no idea if this works without any runtime errors. just started learning OOP.

EDIT_1: output of g++:

In file included from main.cpp:2:
fraction.h:25:17: warning: inline function ‘long int fraction::get_denominator()’ used but never defined
   25 |     inline long get_denominator();
      |                 ^~~~~~~~~~~~~~~
/usr/bin/ld: /tmp/ccvEpbJj.o: in function `main':
main.cpp:(.text+0x35): undefined reference to `fraction::get_denominator()'
collect2: error: ld returned 1 exit status
Fungor
  • 1
  • 1

0 Answers0