Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.67/3: Рейтинг темы: голосов - 3, средняя оценка - 4.67
0 / 0 / 0
Регистрация: 22.12.2013
Сообщений: 3
1

Перегрузка потока ввода вывода в dll

29.05.2016, 16:24. Показов 571. Ответов 2
Метки нет (Все метки)

Доброго времени суток.
Мне нужно создать dll, которая содержит экспортируемый класс для работы с рациональными числами.
Сам класс написал и он хорошо работает.
Dll делаю первый раз. Среда разработки visual studio 2010.
Вроде бы все функции работают, кроме перегрузки потока ввода/вывода.
При компиляции самой dll линкер не ругается, но когда в другом проекте хочу воспользоваться этими методами появляются ошибки:
error LNK2001: неразрешенный внешний символ ""class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class Rational &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01 @AAVRational@@@Z)"
1>C:\Users\tempo\Documents\Visual Studio 2010\Projects\MyLibrary\Debug\nba.exe : fatal error LNK1120: 1 неразрешенных внешних элементов

Заранее спасибо за помощь.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/ MyLibrary.h
 
#pragma once
#ifdef COMPILE_MYLIBRARY  
#define MYLIBRARY_EXPORT __declspec(dllexport) 
#else   
#define MYLIBRARY_EXPORT __declspec(dllimport) 
#endif 
 
#include <cmath>
#include <iostream>
#include <conio.h>
#include <sstream>
#include <string>
 
using namespace std;
class MYLIBRARY_EXPORT Rational
{
private:
    int numerator,denominator;
public:
    Rational();
    Rational(const Rational&);
    Rational(int n,int d);
    ~Rational();
    operator int() const;
    operator double() const;
    operator string() const;
    int get_numerator() const;
    int get_denominator() const;
    void set_numerator (int n);
    void set_denominator(int d);
    int nod(int n, int d);
    int noz(const Rational&, const Rational&);
    Rational& operator~(void);
    Rational& operator=(const Rational&);
    Rational& operator=(const int&);
    Rational& operator=(const double&);
    Rational operator=(const string&);
    Rational operator+(const Rational&) const;
    Rational operator-(const Rational&) const;
    Rational operator*(const Rational&) const;
    Rational operator/(const Rational&) const;
    Rational operator+(int) const;
    Rational operator-(int) const;
    Rational operator*(int) const;
    Rational operator/(int) const;
    bool operator>(const Rational&) const;
    bool operator<(const Rational&) const;
    bool operator>=(const Rational&) const;
    bool operator<=(const Rational&) const;
    bool operator==(const Rational&) const;
    bool operator!=(const Rational&) const;
    friend ostream& operator<<(ostream&, Rational&);
    friend istream& operator >> (istream&, Rational&);
};
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
// Главный DLL-файл.
 
#include "stdafx.h"
#include "MyLibrary.h"
 
 
using namespace std;
 
Rational::Rational(){
    numerator=0; denominator=1;
}
Rational::Rational(const Rational& r){
     this->numerator=r.numerator;
     this->denominator=r.denominator;
    }
Rational::Rational(int n,int d){
    numerator=n;denominator=d;
}
Rational::~Rational()
{}
Rational::operator int() const{ 
    return (numerator)/denominator;
}
Rational::operator double() const{ 
    return ((double)numerator)/denominator;
}
Rational::operator string() const{
    ostringstream ost;//класс потока для работы со строками
                ost << numerator<<"/"<<denominator;
                return ost.str();
}
int Rational::get_numerator() const {
  return numerator;
}
int Rational::get_denominator() const{
    return denominator;
}
 Rational& Rational::operator=( const Rational& r){
     if(this==&r)
         return *this;
     numerator=r.numerator;
     denominator=r.denominator;
     return *this;
 }
 void Rational::set_numerator(int n){
     numerator=n;
 }
 void Rational::set_denominator(int d){
     if (d<=0) 
    {
        cout << "ОШИБКА ! Знаменатель должен быть натуральным числом т.е. положительным и не равым 0" << endl;
        system("pause");
        exit(1);
    }
        denominator=d;
 }
 
 int Rational::nod(int n, int d) {
  int a = abs(n), b = abs(d);
                    while(a!=0 && b!=0){
                        if (a>=b)
                            a = a%b;
                        else
                            b = b%a;
                    }
                    return a+b;
 }
  int Rational::noz(const Rational& r1, const Rational& r2){
        int NOD=nod(r1.denominator,r2.denominator),
        pr=r1.denominator*r2.denominator;
        return pr/NOD;
    }
  Rational& Rational::operator~(void) {
    if(numerator !=0)
    {
        int NOD = nod(numerator,denominator);
        if(NOD !=1)
        {
            numerator /= NOD;
            denominator /=NOD;
        }
    }
    return *this;
}
   Rational& Rational::operator=( const int& q){
     numerator=q;
       denominator=1;
       return *this;
 }
     Rational& Rational::operator=( const double& q){
    string stroka;
            ostringstream ost;//класс потока для работы со строками
            ost << q;
             stroka = ost.str();
              string posle_zap = stroka.substr(stroka.find('.')+1, stroka.length());//+1 ,чтоб не выводил точку
              int chisel_posle_zap = posle_zap.length();//считаем кол-во чисел после запятой для формирования знаменателя
                double znach_posle=atof(posle_zap.c_str()); //преобразуем строку в число 
                int num,den;
                den = int(pow(10.0,chisel_posle_zap));
                if (q>=0)
                num=(int(q)*den)+int(znach_posle);
                else
                num=(int(q)*den)-int(znach_posle);
                numerator=num;
                denominator=den;
       return *this;
 }
 Rational Rational::operator=( const string& s){
    size_t proverka =s.find('/'); //ищем в строке '/'
                if (proverka == string::npos) {cout << "Знак деления не найден"<< endl;system("pause");exit(1);}
                else
                {
                string n = s.substr(0, s.find('/'));
                string d = s.substr(s.find('/')+1, s.length());
                int num = atoi(n.c_str()), den=atoi(d.c_str());
                this->set_numerator(num);this->set_denominator(den);
                }
                return *this;
 }
Rational Rational::operator+(const Rational& r) const {
    return Rational(numerator*r.denominator+denominator*r.numerator,denominator*r.denominator);
}
 
Rational Rational::operator-(const Rational& r) const {
    return Rational(numerator*r.denominator-denominator*r.numerator,denominator*r.denominator);
}
 
Rational Rational::operator*(const Rational& r) const {
    return Rational(numerator*r.numerator,denominator*r.denominator);
}
 
Rational Rational::operator/(const Rational& r) const {
    return Rational(numerator*r.denominator,denominator*r.numerator);
}
 
Rational Rational::operator+(int q) const {
    return Rational(numerator+q*denominator,denominator);
}
 
Rational Rational::operator-(int q) const {
    return (*this) + (-q);
}
 
Rational Rational::operator*(int q) const {
    return Rational(numerator*q,denominator);
}
 
Rational Rational::operator/(int q) const {
    return Rational(numerator,q*denominator);
}
bool Rational::operator>(const Rational& r) const {
    return double (*this) > double(r);
}
 
bool Rational::operator<(const Rational& r) const {
    return r>*this;
}
 
bool Rational::operator==(const Rational& r) const {
    return numerator*r.denominator == denominator*r.numerator;
}
 
bool Rational::operator!=(const Rational& r) const {
    return !(*this == r);
}
 
bool Rational::operator<=(const Rational& r) const {
    return !(*this > r);
}
 
bool Rational::operator>=(const Rational& r) const {
    return !(*this<r);
}
ostream& operator<<(ostream& out, Rational& a){
    //если числитель дроби 0, то это число 0
    if (a.numerator == 0)
        out << "0";
    // если числитель не равен 0
    if (a.numerator !=0)
        out << a.numerator << "/" <<a.denominator;
    else out << " ";
    return out;
}
 
 
//операция ввода дроби
istream& operator>> (istream& in, Rational& a){
in >> a.numerator;
    char sym;
    in >> sym;
    if(sym == '/')
        in >> a.denominator;
    else {
        cout << "Ошбика ввода!" << endl;
        exit(1);
    }
    if (a.denominator<=0) 
    {
        cerr << "ОШИБКА ! Знаменатель должен быть натуральным числом т.е. положительным и не равым 0" << endl;
        exit(1);
    }
    return in;
    }
Добавлено через 13 минут
Попробовал перенести реализацию дружественных функций в файл с объявлением класса, заработало.
Можно ли как то сделать, чтоб описание и реализация были в разных файлах и перегрузка работало в других проектах?
0

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
29.05.2016, 16:24
Ответы с готовыми решениями:

Перегрузка ввода/вывода в/из потока
Никогда потоками не пользовался, поэтому не знаю. Как перегрузить для ввода из потока оператор...

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

Перегрузка операторов ввода и вывода из потока в шаблонном классе
Доброго времени суток. Пишу свой вектор. В нём надо перегрузить вышеназванные операторы. Vector.h...

Перегрузка потока ввода
Помогите мне пожалуйста. Пыта #include &lt;iostream&gt; #include &lt;conio.h&gt; using namespace std; ...

2
Жарю без масла
867 / 749 / 225
Регистрация: 13.01.2012
Сообщений: 1,702
29.05.2016, 16:28 2
то, что ваши операторы <</>> объявлены в классе как friend, не делает их членами класса. соответственно их тоже нужно делать MYLIBRARY_EXPORT
1
0 / 0 / 0
Регистрация: 22.12.2013
Сообщений: 3
29.05.2016, 16:36  [ТС] 3
Совсем забыл про это.Спасибо Вам большое,что пояснили. Работает!
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
29.05.2016, 16:36

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

Перегрузка вывода и ввода
Здравствуйте прошу помочь ,написал программу в ней нужно перегрузить вывод и ввод ,как это можно...

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

Перегрузка потокового ввода/вывода
Вот сама перегрузка ostream&amp; operator&lt;&lt; (ostream&amp; out, Poli&amp; outstream) { out&lt;&lt;&quot;Степень...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.