Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

C++

Войти
Регистрация
Восстановить пароль
 
Jauhien41
0 / 0 / 0
Регистрация: 05.10.2014
Сообщений: 4
#1

Ошибки LNK2001 и LNK1120 - C++

30.11.2014, 13:17. Просмотров 463. Ответов 14
Метки нет (Все метки)

Наверное, какая-то нубская ошибка в синтаксисе, но я не знаю, что с этим делать
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
//файл complex.h
#ifndef _COMPLEX_
#define _COMPLEX_
 
#include <math.h>
 
class Complex
{
public: 
        Complex(double re=0, double im=0){m_re=re; m_im=im; s_count++;}
        Complex(Complex &obj) {m_re=obj.m_re; m_im=obj.m_im; s_count++;}
        ~Complex() {s_count--;}
 
        void setRe(const double re) {m_re=re;}
        void setIm(const double im) {m_im=im;}
        double getRe() const {return m_re;}
        double getIm() const {return m_im;}
 
        Complex plus(const Complex &obj1, const Complex &obj2) {m_re=obj1.m_re+obj2.m_re; m_im=obj1.m_im+obj2.m_im; return *this;}
        Complex minus(const Complex &obj1, const Complex &obj2) {m_re=obj1.m_re-obj2.m_re; m_im=obj1.m_im-obj2.m_im; return *this;}
        double abs() const {return sqrt(m_re*m_re+m_im*m_im);}
        int sravn(const Complex &obj) const;
        void out() const;
        int getCount() const {return s_count;}
private:    
        double m_re, m_im;
        static int s_count;
};
#endif
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//файл complex.cpp
#include "complex.h"
#include <iostream>
 
int Complex::sravn(const Complex &obj) const
{
    if (abs()>obj.abs())
        return 1;
    if (abs()<obj.abs())
        return -1;
    return 0;
}
 
void Complex::out() const
{
    std::cout << m_re;
    if (m_im!=0)
        if (m_im>0)
            std::cout << "+" << m_im << "i";
        else
            std::cout << "-" << m_im << "i";
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
//файл main.cpp
#include "complex.h"
#include <iostream>
 
using namespace std;
 
int main()
{
    Complex c1;
    system("pause");
    return 0;
}
Если убрать первую строку мэйна: Complex c1; - билдится, а так:
error LNK2001: unresolved external symbol "private: static int Complex::s_count" (?s_count@Complex@@0HA)
fatal error LNK1120: 1 unresolved externals
0
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.11.2014, 13:17
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Ошибки LNK2001 и LNK1120 (C++):

Статический поток - error LNK1120 error LNK2001 - Visual C++
в классе есть статический поток типа fstream, в который будут сливаться данные, все гуд а линковщик не пускает=( Error 2 error...

error LNK2001: unresolved external symbol---fatal error LNK1120: 4 unresolved externals - Visual C++
Здравствуйте! Занимаюсь программированием не очень долго, прошу объяснить в доступных терминах для начинающего. Выполняя задание, добавил...

MFC. Ошибка LNK2019 , LNK1120 - Visual C++
Работаю в среде MFC: bool CheckKey() { for (int i=1; i&lt;= Key.GetLength(); i++) for (int j=1; j &lt;= Key.GetLength(); j++) ...

LNK2001 KeyBoardProc - Visual C++
Ошибка 1 error LNK2001: неразрешенный внешний символ &quot;&quot;long __stdcall KeyboardProc(int,unsigned int,long)&quot;...

LNK2001 в статической функции - Visual C++
в некотором приложении пришлось работать с сокетами, решил сделать враперы, все вроде ничего, но вот только взяло и вылезло: ...

Неубиваемые LNK2019 и LNK2001 - Visual C++
Я ужо задолбался с этой дохрена-непонятной ошибкой которая обозначает великое НИЧТО! LNK2019 = LNK2001 = смысл(NULL) Она не указывает...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Байт
Эксперт C
16051 / 10320 / 1540
Регистрация: 24.12.2010
Сообщений: 19,438
30.11.2014, 14:24 #2
Цитата Сообщение от Jauhien41 Посмотреть сообщение
private:* *
* * * * double m_re, m_im;
* * * * static int s_count;
Переставь это наверх, перед конструктором.
Второй вариант - вынеси реализацию конструктора из h-хедера в cpp

Добавлено через 1 минуту
Третий - сделай приватные данные публичными
0
Jauhien41
0 / 0 / 0
Регистрация: 05.10.2014
Сообщений: 4
30.11.2014, 14:39  [ТС] #3
Первое не помогло, второе и третье не приветствуется преподом. И тоже не помогло
0
Байт
Эксперт C
16051 / 10320 / 1540
Регистрация: 24.12.2010
Сообщений: 19,438
30.11.2014, 14:49 #4
Jauhien41, Нет конструктора без параметров.
Компилятор видит "Complex c1;" Он же не просто выделяет память, как для int скажем. Он должен конструктор позвать. А его нет

Добавлено через 4 минуты
Jauhien41, Извиняюсь, ошибся. Конструктор без параметров у тебя есть (с умалчиваемыми параметрами) Но меня смущает, что s_count нигде не инициализируется
0
Jauhien41
0 / 0 / 0
Регистрация: 05.10.2014
Сообщений: 4
30.11.2014, 15:05  [ТС] #5
Мне тоже это не очень нравится, но не знаю, где это сделать
0
DrOffset
7134 / 4275 / 963
Регистрация: 30.01.2014
Сообщений: 7,064
30.11.2014, 15:35 #6
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от Jauhien41 Посмотреть сообщение
static int s_count;
У тебя отсутствует определение этой переменной (определение статических переменных класса нужно делать таким же образом, каким ты делаешь определение функций).
Т.е. в cpp надо сделать так (complex.cpp):
C++
1
int Complex::s_count = 0;
3
Байт
Эксперт C
16051 / 10320 / 1540
Регистрация: 24.12.2010
Сообщений: 19,438
30.11.2014, 17:35 #7
Цитата Сообщение от DrOffset Посмотреть сообщение
в cpp надо сделать так
Понимаете, исторически сложилось так, что я - чистый сишник (процедурный). И не все парадигмы плюсов мне понятны. Одна из них - статические члены класса. Это одна из причин, почему я ими не пользуюсь. Мне не очень понятно, почему бы начальное присвоение стат-члену не сделать прямо в описании класса? И как вяжется присвоение ему значения в майне с тем, что он приватный? Хотя ясно, что это вопросы не к вам, а к Б.Страуструппу. Но я в повседневной практике стараюсь использования статических членов избегать.
0
DrOffset
7134 / 4275 / 963
Регистрация: 30.01.2014
Сообщений: 7,064
30.11.2014, 17:54 #8
Цитата Сообщение от Байт Посмотреть сообщение
Мне не очень понятно, почему бы начальное присвоение стат-члену не сделать прямо в описании класса?
Это связано с понятие linkage. Дело в том, что у статических переменных класса внешнее связывание. В таком случае, если каким-либо образом оставить их определение в h, то у нас появятся ошибки множественного определения. Эквивалент такого кода на С:
C
1
2
3
/*some.h*/
 
int s_count = 0;
Если мы включим этот файл в более чем один *.с, то получим ошибки линковщика насчет множественного определения. Поэтому на С мы бы написали так:
C
1
2
3
4
5
6
7
8
/*some.h*/
 
extern int s_count; // объявление
 
/*some.c*/
#include "some.h"
 
int s_count = 0; // определение
ничего не напоминает?

PS. Если детализированность ответа все еще неудовлетворительная, и что-то все равно не понятно, то спрашивай, я разверну еще. Давай добивать этот вопрос до конца
2
Байт
Эксперт C
16051 / 10320 / 1540
Регистрация: 24.12.2010
Сообщений: 19,438
30.11.2014, 18:18 #9
DrOffset, спасибо! Все вполне понятно. И пример на Си меня убедил окончательно (кстати, именно так я и поступаю) Мое предложение (о присвоение прямо в описании класса) вызвало бы еще одну заплатку в логике С++, а их там и без того хватает... Чисто эстетически и логически хотелось бы иметь такую возможность, но что делать, можно выбирать язык, но уж если выбрал - принимай его парадигмы!
Остался 1 маленький вопрос. Как "int Complex::s_count = 0;" согласуется с его приватностью? Ведь ни в одном из
методов, не являющихся методами класса Complex этого писать нельзя. А методах класса - просто глупо.
Или это просто пишется "сверху", вне функций? Когда-то я не смог выбраться из этого лабиринта, может быть получится сейчас?
0
DrOffset
7134 / 4275 / 963
Регистрация: 30.01.2014
Сообщений: 7,064
30.11.2014, 18:23 #10
Цитата Сообщение от Байт Посмотреть сообщение
Остался 1 маленький вопрос. Как "int Complex::s_count = 0;" согласуется с его приватностью? Ведь ни в одном из
методов, не являющихся методами класса Complex этого писать нельзя. А методах класса - просто глупо.
Точно так же, как согласуется вот это:
C++
1
2
3
4
5
6
7
8
9
10
11
12
class A
{
private:
    void foo(); // private!
};
 
//cpp
 
void A::foo() // <------
{
//.....
}
Иными словами - это не доступ. Это операция разрешения области видимости, для определения функции. Со статической переменной ровно тоже самое.

Цитата Сообщение от Байт Посмотреть сообщение
Или это просто пишется "сверху", вне функций?
Именно.
2
Байт
Эксперт C
16051 / 10320 / 1540
Регистрация: 24.12.2010
Сообщений: 19,438
30.11.2014, 18:32 #11
Ага! статическая переменная класса - это фактически extern вот с таким длинным именем Complex::s_count Но использовать ее внутри функций нельзя (приватная). Нельзя также писать extern Complex::s_count. Только вне функций, только один раз (чтоб линковщик не рыдал)
Более того, описания ее в классе недостаточно (ее нет, память не выделена, ссылка не определена)
Надо именно где-то в другом исходнике ее написать. Вот тут-то она и получает свой кусок памяти, на который уже ссылаются все другие ее вхождения...
Я правильно понимаю?

Добавлено через 4 минуты
Цитата Сообщение от DrOffset Посмотреть сообщение
Точно так же, как согласуется вот это:
Простите, но тут я уже совсем ничего не понял. Приватный метод нельзя вызвать ни из какого места, кроме методов класса!
0
DrOffset
7134 / 4275 / 963
Регистрация: 30.01.2014
Сообщений: 7,064
30.11.2014, 18:43 #12
Цитата Сообщение от Байт Посмотреть сообщение
Нельзя также писать extern Complex::s_count.
extern тоже определяет внешнее связывание (например для констант, у которых по-умолчанию - внутренее). Кроме того, обычная глобальная переменная (без каких либо дополнительных ключевых слов) тоже определяет внешнее связывание. И статик переменная внутри класса - тоже. А вот статик переменная вне класса - определяет внутреннее связывание.
Многим (и мне тоже), кстати, очень не нравится такая перегруженность смыслами этого ключевого слова (static). Но из песни слова уже не выкинуть.

Цитата Сообщение от Байт Посмотреть сообщение
Я правильно понимаю?
Да, правильно

Добавлено через 38 секунд
Цитата Сообщение от Байт Посмотреть сообщение
Простите, но тут я уже совсем ничего не понял.
Его можно вызывать из других методов этого же класса.

Добавлено через 4 минуты
Цитата Сообщение от Байт Посмотреть сообщение
Простите, но тут я уже совсем ничего не понял.
Так это не вызов на картинке выше. Это определение метода в cpp.
2
Байт
Эксперт C
16051 / 10320 / 1540
Регистрация: 24.12.2010
Сообщений: 19,438
30.11.2014, 19:03 #13
Цитата Сообщение от DrOffset Посмотреть сообщение
Так это не вызов на картинке выше. Это определение метода в cpp.
Простите, не разглядел...
Да, теперь все стало на свои места.
Спасибо.

Добавлено через 13 минут
DrOffset, Последний (надеюсь) вопрос. Вот я решил все статик-переменные класса инициализировать в одном месте. Статической функцией
C++
1
Complex::Init() { s_count = 0; }
ИМХО, этого не достаточно (опять линкер обидится). Нужно все равно где-то написать
C++
1
int Complex::s_count;
Так?
0
DrOffset
7134 / 4275 / 963
Регистрация: 30.01.2014
Сообщений: 7,064
30.11.2014, 19:14 #14
Цитата Сообщение от Байт Посмотреть сообщение
Так?
Да. Только задание значения в функции уже не будет инициализацией. Это будет присваивание.
1
Jauhien41
0 / 0 / 0
Регистрация: 05.10.2014
Сообщений: 4
30.11.2014, 19:41  [ТС] #15
Спасибо, теперь всё работает
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
30.11.2014, 19:41
Привет! Вот еще темы с ответами:

LNK2001 шаблон функции - Visual C++
Здравствуйте! Ошибка линковщика: 1&gt;map.obj : error LNK2001: unresolved external symbol &quot;class sf::Vector2&lt;float&gt; __cdecl...

LNK2001 при использовании liblzma - Visual C++
#include &lt;iostream&gt; #include &lt;Windows.h&gt; #include &lt;fstream&gt; #include &quot;lzma.h&quot; using namespace std; std::string...

adodb.obj : error LNK2001:__imp__executor_globals_id - Visual C++
Доброе время суток, знатоки. Сразу скажу, что я программист по PHP и Си для темный лес. Проблема в следующем, имеется .dll для...

error LNK2001: unresolved external symbol_mainCRTStartup - Visual C++
Помогите пожалуста разобраться. Написал самую что ни на есть простейшую программу, и в ней нашлись ошибки. Ошибки две: 1. error...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
30.11.2014, 19:41
Ответ Создать тему
Опции темы

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