0

I have a problem when linking the .cpp and the .h files.

Here is my code:

cpp

#include "Number.h"
#include <string.h>

Number::Number(const char* value, int baza)
{
    val = new char[strlen(value)+1];
    memcpy(val, value, strlen(value) + 1);
    this->base = baza;
}

Number::Number(char* value, int baza)
{
    val = new char[strlen(value) + 1];
    memcpy(val, value, strlen(value) + 1);
    this->base = baza;
}

Number::~Number()
{
    delete val;
    val = nullptr;
}

Number operator+(Number& i1, Number& i2)
{
    int x = char_to_10(i1.getVal(), i1.GetBase()) + char_to_10(i2.getVal(), i2.GetBase());
    cout << x<<endl;
    int baza_mare = (i1.GetBase() > i2.GetBase() ? i1.GetBase() : i2.GetBase());
    char* p = new char[10];
    p=SchimbaBaza(x, baza_mare);
    Number res(p, baza_mare);
    return res;
}

char* SchimbaBaza(int n, int newBase)
{
    int i = 0; int p = 0; int v[1000];
    while (n)
    {
        v[i] = n % newBase;
        i++;
        p++;
        n = n / newBase;
    }
    int j = 0;
    char* aux = new char[p];
    for (i = 0; i <= p; i++)
        aux[i] = NULL;
    for (i = p-1; i >= 0; i--)
    {
        if (v[i] <= 9)
            aux[j++] = (char)(v[i] + 48);
        else if (v[i] == 10)
            aux[j++] = 'A';
        else if (v[i] == 11)
            aux[j++] = 'B';
        else if (v[i] == 12)
            aux[j++] = 'C';
        else if (v[i] == 13)
            aux[j++] = 'D';
        else if (v[i] == 14)
            aux[j++] = 'E';
        else if (v[i] == 15)
            aux[j++] = 'F';
    }
    return aux;
}

void Number::SwitchBase(int newBase)
{
    int i = 0; int p = 0; int v[1000];
    char aux[100];
    int n = char_to_10(getVal(), GetBase());
    while (n)
    {
        v[i] = n % newBase;
        i++;
        p++;
        n = n / newBase;
    }
    int j = 0;
    for (i = p; i >= 0; i--)
    {
        if (v[i] <= 9)
            aux[j++]= (char)(v[i]+48);
        else if (v[i] == 10)
            aux[j++]= 'A';
        else if (v[i] == 11)
            aux[j++] = 'B';
        else if (v[i] == 12)
            aux[j++] = 'C';
        else if (v[i] == 13)
            aux[j++] = 'D';
        else if (v[i] == 14)
            aux[j++] = 'E';
        else if (v[i] == 15)
            aux[j++] = 'F';
    }

    this->base = newBase;
    j = 0;
    for (j = 1; j <=p; j++)
        cout<<aux[j];
    cout << endl;
    for (j = 0; j <p; j++)
        val[j] = NULL;
    for (j = 0; j < p; j++)
        val[j] = aux[j+1];
}

char* Number::getVal()
{
    return (this->val);
}

int Number::GetDigitsCount()
{
    return (strlen(this->val));
}

int Number::GetBase()
{
    return(this->base);
}

void Number::Print()
{
    printf("Numarul nostru in baza %d este %s.\n", this->base, this->val);
}

int char_to_10(const char* text, int baze)
{
    int x = 0;
    char * s = new char[strlen(text) + 1];
    memcpy(s, text, (strlen(text) + 1));
    for (int i = 0; i < strlen(s); i++)
    {
        if (s[i] >= '0' && s[i] <= '9')
            x = x + (s[i] - '0') * pow(baze, (strlen(s) - i - 1));
        if (s[i] == 'A')
            x = x + 10 * pow(baze, (strlen(s) - i - 1));
        if (s[i] == 'B')
            x = x + 11 * pow(baze, (strlen(s) - i - 1));
        if (s[i] == 'C')
            x = x + 12 * pow(baze, (strlen(s) - i - 1));
        if (s[i] == 'D')
            x = x + 13 * pow(baze, (strlen(s) - i - 1));
        if (s[i] == 'E')
            x = x + 14 * pow(baze, (strlen(s) - i - 1));
        if (s[i] == 'F')
            x = x + 15 * pow(baze, (strlen(s) - i - 1));
    }
    return x;
}

header

#pragma once
#include <string.h>
#include <iostream>
using namespace std;

class Number
{
    char* val;
    int base;
public:
    Number(const char* value, int baza); // where base is between 2 and 16
    Number(char* value, int baza);
    ~Number();

    friend Number operator +(Number& i1, Number& i2);
    friend bool operator -(const Number& i1, const Number& i2);
    bool operator !();
    bool operator[](int index);
    bool operator>(const Number& i);
    Number(const Number& i);
    Number(const Number&& i);
    bool operator--();
    bool operator--(int value);

    void SwitchBase(int newBase);
    void Print();
    char* getVal();
    int  GetDigitsCount(); // returns the number of digits for the current number
    int  GetBase(); // returns the current base
};

int char_to_10(const char* text, int baze);
char* SchimbaBaza(int n, int newBase);

main

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

int main()
{
    Number n1("14A", 12);
    printf("Avem numarul de %d cifre in baza %d.\n", n1.GetDigitsCount(), n1.GetBase());
    n1.Print();
    //n1.~Number();
    //n1.SwitchBase(10);
    //n1.Print();
    printf("obiectul nostru are valoarea %s\n",n1.getVal());
    //n1.SwitchBase(10);
    //cout << char_to_10(n1.getVal(), n1.GetBase());
    //cout << endl;
    //n1.SwitchBase(10);
    //printf("obiectul nostru are valoarea %s\n", n1.getVal());
    Number n2("19A", 13);
    Number n3 = n1 + n2;    
}

The error I get is:

LNK2019 unresolved external symbol "public: __thiscall Number::Number(class Number const &&)" (??0Number@@QAE@$$QBV0@@Z) referenced in function "class Number __cdecl operator+(class Number &,class Number &)" (??H@YA?AVNumber@@AAV0@0@Z)

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Bianca0745
  • 23
  • 5
  • Did you link both the result of main and Number together into the final executable? – tadman May 13 '20 at 18:46
  • @tadman yes, the other functions work fine. My problem is with operator+. – Bianca0745 May 13 '20 at 18:47
  • As a note, when posting here try and trim out anything not directly related to the problem at hand. There's a lot of code here that has nothing to do with this issue. – tadman May 13 '20 at 18:49
  • 3
    Your `Number(Number const &&)` looks all wrong. It should be `Number(Number&&);` and you haven't implemented it. – Ted Lyngmo May 13 '20 at 18:49
  • So, where did you define `Number(const Number&&)`? I don't see it in your code. – Asteroids With Wings May 13 '20 at 18:49
  • @TedLyngmo that's right, i didn't get there yet but i thought i don't need that for my operator+ – Bianca0745 May 13 '20 at 18:49
  • 1
    It's also odd that your `operator-` has `const` args but your `operator+` does not. It's also time to use `std::string` instead of `new char[...]`. – tadman May 13 '20 at 18:50
  • 2
    `using namespace std;` is a terrible idea generally. It's worse in a header. – sweenish May 13 '20 at 18:50
  • You haven't implemented the copy constructor either? If you had, it would have chosen that instead. – Ted Lyngmo May 13 '20 at 18:50
  • 1
    `operator-()` returns a bool while `operator+()` returns a Number. Why the difference? – sweenish May 13 '20 at 18:53
  • @TedLyngmo could you please tell me why would the copy/move constructors change the behavior of my operator+ ? I'm confused – Bianca0745 May 13 '20 at 18:54
  • @sweenish i only use using namespace std for fast cin/cout while testing, but i can as well remove it when i'm done. as for the - operator, i haven't implemented it yet. i am stuck at the + one – Bianca0745 May 13 '20 at 18:55
  • @Bianca0745 That's a poor reason for a bad practice. Two lines: `using std::cin;` and `using std::cout;` solve that problem. – sweenish May 13 '20 at 18:56
  • @sweenish i know, but tell that to our high school teachers as well lol. however, i'm pretty sure that's not what causes my linking problem here. – Bianca0745 May 13 '20 at 18:58
  • 1
    The `n1 + n2` in `Number n3 = n1 + n2;` creates a temporary. This can be moved or copied into `n3` when `n3` is constructed, so you need a copy constructor and/or move constructor. Another note: If you make the `operator+` signature like this: `Number operator+(Number i1, const Number& i2);` you can do `return i1 += i2;` in the function - if you start by implementing `operator+=` which is usually a good first step. – Ted Lyngmo May 13 '20 at 18:59
  • When hunting for bugs you want to make the code under test as small as possible. The first things to go should be stuff like `using namespace std;` that are known to be risky practice. – user4581301 May 13 '20 at 18:59
  • 1
    Handy reading: [What are the basic rules and idioms for operator overloading?](https://stackoverflow.com/questions/4421706/what-are-the-basic-rules-and-idioms-for-operator-overloading) Much wisdom packed in that Q&A. – user4581301 May 13 '20 at 19:02
  • 1
    @TedLyngmo I see, thank you! – Bianca0745 May 13 '20 at 19:02
  • @user4581301 I'll keep that in mind, thank you! – Bianca0745 May 13 '20 at 19:03
  • Another note: If you start by implementing `Number& Number::operator+=(const Number&);` (and `operator-=`) you won't need to make the free functions `operator+` and `operator-` friends since they will just call the member function `operator+=` and `operator-=`. – Ted Lyngmo May 13 '20 at 19:08

1 Answers1

-1

No definition for functions:

Number(const Number& i);
Number(const Number&& i);
user9559196
  • 157
  • 6