2

При компиляции ошибка: ссылка на неразрешенный внешний символ "class Mass __cdecl operator*(class Mass &,long)" (??D@YA?AV?$Mass@J@@AAV0@J@Z) в функции _main. lab18.3 D:\Лабараторки\lab18\lab18.3\lab18.3\Source.obj 1

#include <iostream>
#include <locale.h>
using namespace std;
template <class T>
class Mass
{
private:
    long double* p;
    int sizemass;
public:
    Mass() {
        sizemass = 1;
        p = new long double[1];
        p[0] = 10;
    }
    Mass(long x)
    {
        sizemass = x;
        p = new long double[x];
    }
    Mass(long x, long double znach)
    {
        sizemass = x;
        p = new long double[x];
        for (int i = 0; i < x; i++) {
            p[i] = znach;
        }
    }
    Mass(const Mass<T>& object)
    {
        this->p = object.p;
        this->sizemass = sizemass;
    }
    ~Mass() {
        delete[] p;
    }
    void out(void) {
        for (int i = 0; i < sizemass; i++) {
            cout << p[i];
        }
    }
    Mass<T> operator = (T znach) {
        for (int i = 0; i < sizemass; i++) {
            this->p[i] = znach;
        }
        return *this;
    }
Mass&lt;T&gt; operator += (T znach) {
    for (int i = 0; i &lt; this-&gt;sizemass; i++) {
        this-&gt;p[i] = this-&gt;p[i] + znach;
    }
    return *this;
}

Mass&lt;T&gt; operator -= (T znach) {
    for (int i = 0; i &lt; this-&gt;sizemass; i++) {
        this-&gt;p[i] = this-&gt;p[i] - znach;
    }
    return *this;
}

Mass&lt;T&gt; operator *= (T znach) {
    for (int i = 0;i &lt; this-&gt;sizemass; i++) {
        this-&gt;p[i] = this-&gt;p[i] * znach;
    }
    return *this;
}

Mass&lt;T&gt; operator [] (int x) {
    return this-&gt;p[x];
}
friend Mass&lt;T&gt; operator + (Mass&lt;T&gt;&amp; object1, T znach);
friend Mass&lt;T&gt; operator - (Mass&lt;T&gt;&amp; object1, T znach);
friend Mass&lt;T&gt; operator * (Mass&lt;T&gt;&amp; object1, T znach);

};

template <class T> Mass<T> operator + (Mass<T>& object1, T znach) { Mass temp; for (int i = 0; i < object1.sizemass; i++) { temp.p[i] = object1.p[i] + znach; } return temp; }

template <class T> Mass<T> operator - (Mass<T>& object1, T znach) { Mass temp; for (int i = 0; i < object1.sizemass; i++) { temp.p[i] = object1.p[i] - znach; } return temp; }

template <class T> Mass<T> operator * (Mass<T>& object1, T znach) { Mass temp; for (int i = 0; i < object1.sizemass; i++) { temp.p[i] = object1.p[i] * znach; } return temp; }

int main() { setlocale(LC_ALL, ""); Mass<long> v(8); Mass<long> m(6); m + 1; cin.get(); return 0; }

1 Answers1

1

Довольно интересный вопрос. Проблема здесь, насколько я понял, в связке шаблонов и дружественных функций.

Итак, чтобы всё заработало, нужно:

  1. Продублировать template<class T> перед объявлением дружественных функций внутри класса.
  2. Явно указать тип второго слагаемого в 4ой строке функции main с помощью строкового литерала.

По итогу код будет выглядеть так:

#include <iostream>
#include <locale.h>
using namespace std;
template <class T>
class Mass
{
private:
    long double* p;
    int sizemass;
public:
    Mass() {
        sizemass = 1;
        p = new long double[1];
        p[0] = 10;
    }
    Mass(long x)
    {
        sizemass = x;
        p = new long double[x];
    }
    Mass(long x, long double znach)
    {
        sizemass = x;
        p = new long double[x];
        for (int i = 0; i < x; i++) {
            p[i] = znach;
        }
    }
    Mass(const Mass<T>& object)
    {
        this->p = object.p;
        this->sizemass = sizemass;
    }
    ~Mass() {
        delete[] p;
    }
    void out(void) {
        for (int i = 0; i < sizemass; i++) {
            cout << p[i];
        }
    }
    Mass<T> operator = (T znach) {
        for (int i = 0; i < sizemass; i++) {
            this->p[i] = znach;
        }
        return *this;
    }
Mass&lt;T&gt; operator += (T znach) {
    for (int i = 0; i &lt; this-&gt;sizemass; i++) {
        this-&gt;p[i] = this-&gt;p[i] + znach;
    }
    return *this;
}

Mass&lt;T&gt; operator -= (T znach) {
    for (int i = 0; i &lt; this-&gt;sizemass; i++) {
        this-&gt;p[i] = this-&gt;p[i] - znach;
    }
    return *this;
}

Mass&lt;T&gt; operator *= (T znach) {
    for (int i = 0; i &lt; this-&gt;sizemass; i++) {
        this-&gt;p[i] = this-&gt;p[i] * znach;
    }
    return *this;
}

Mass&lt;T&gt; operator [] (int x) {
    return this-&gt;p[x];
}

template &lt;class T&gt; // !!!
friend Mass&lt;T&gt; operator + (Mass&lt;T&gt;&amp; object1, T znach);
friend Mass&lt;T&gt; operator - (Mass&lt;T&gt;&amp; object1, T znach);
friend Mass&lt;T&gt; operator * (Mass&lt;T&gt;&amp; object1, T znach);

};

template <class T> Mass<T> operator + (Mass<T>& object1, T znach) { Mass<T> temp; for (int i = 0; i < object1.sizemass; i++) { temp.p[i] = object1.p[i] + znach; } return temp; }

template <class T> Mass<T> operator - (Mass<T>& object1, T znach) { Mass<T> temp; for (int i = 0; i < object1.sizemass; i++) { temp.p[i] = object1.p[i] - znach; } return temp; }

template <class T> Mass<T> operator * (Mass<T>& object1, T znach) { Mass<T> temp; for (int i = 0; i < object1.sizemass; i++) { temp.p[i] = object1.p[i] * znach; } return temp; }

int main() { setlocale(LC_ALL, ""); Mass<long> v(8); Mass<long> m(6); m + 1l; // l показывает, что 1 имеет тип long cin.get(); return 0; }

Первый пункт нашёл здесь, погуглив про связку шаблонов и друзей.

Затрудняюсь назвать причины необходимости дублирования template <class T> перед объявлением дружественных функций. Возможно, это просто жёсткое требование синтаксиса, а может, за этим стоит что-то большее. В любом случае, надеюсь, найдётся эксперт, который прояснит ситуацию в комментарии или отдельном ответе.

Насчёт второго пункта всё проще – число 1, не являясь переменной, у которой указан тип, по умолчанию имеет тип int, если иное не указано с помощью литерала. Таким образом, когда Вы делаете m + 1, у Вас вызывается шаблонная функция Mass<T> operator + (Mass<T>& object1, T znach), где первый аргумент имеет тип Mass<long>, а второй аргумент – int. Но т.к., согласно шаблону, параметр первого аргумента и тип второго должны совпадать, необходимо 1 явно привести к типу long с помощью литерала l.

V-Mor
  • 5,127