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

C++

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

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

30.11.2014, 13:17. Просмотров 438. Ответов 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
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.11.2014, 13:17     Ошибки LNK2001 и LNK1120
Посмотрите здесь:

Ошибка LNK2001 и LNK1120 - C++
#include &lt;math.h&gt; #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; const double dt=1e-3; const double g=9.81; double fly(double U,...

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

Разбор Ошибки LNK1120 - C++
Как посмотреть что за неразрешенные элементы ? P/s/ Вообще вопрос вытек от сюда...

Ошибки LNK2001 - C++
Здравствуйте! Подскажите, как исправить ошибки: Error 7 error LNK2001: unresolved external symbol &quot;public: static struct...

Ошибки LNK2001 - C++
Всем привет! Возникают ошибки линкования, я не знаю почему? P.S. использую паттерн &quot;Декоратор&quot; Код функции main#include &quot;stdafx.h&quot; ...

Ошибки LNK2001 в библиотеках - C++
Добрый день! Подключил библиотеку SFML к проекту, и в результате получил такие ошибки. Причем, используя Visual Studio 2008 ошибки не...

Ошибки LNK2001 и С2664 в Visual Studio 2008 - C++
Здравствуйте! При написании простой программы запуска Блокнота у меня возникла проблема с Кодировкой. При включенном параметре...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Байт
Эксперт C
15839 / 10166 / 1522
Регистрация: 24.12.2010
Сообщений: 19,166
30.11.2014, 14:24     Ошибки LNK2001 и LNK1120 #2
Цитата Сообщение от Jauhien41 Посмотреть сообщение
private:* *
* * * * double m_re, m_im;
* * * * static int s_count;
Переставь это наверх, перед конструктором.
Второй вариант - вынеси реализацию конструктора из h-хедера в cpp

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

Добавлено через 4 минуты
Jauhien41, Извиняюсь, ошибся. Конструктор без параметров у тебя есть (с умалчиваемыми параметрами) Но меня смущает, что s_count нигде не инициализируется
Jauhien41
0 / 0 / 0
Регистрация: 05.10.2014
Сообщений: 4
30.11.2014, 15:05  [ТС]     Ошибки LNK2001 и LNK1120 #5
Мне тоже это не очень нравится, но не знаю, где это сделать
DrOffset
7058 / 4199 / 949
Регистрация: 30.01.2014
Сообщений: 6,965
30.11.2014, 15:35     Ошибки LNK2001 и LNK1120 #6
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от Jauhien41 Посмотреть сообщение
static int s_count;
У тебя отсутствует определение этой переменной (определение статических переменных класса нужно делать таким же образом, каким ты делаешь определение функций).
Т.е. в cpp надо сделать так (complex.cpp):
C++
1
int Complex::s_count = 0;
Байт
Эксперт C
15839 / 10166 / 1522
Регистрация: 24.12.2010
Сообщений: 19,166
30.11.2014, 17:35     Ошибки LNK2001 и LNK1120 #7
Цитата Сообщение от DrOffset Посмотреть сообщение
в cpp надо сделать так
Понимаете, исторически сложилось так, что я - чистый сишник (процедурный). И не все парадигмы плюсов мне понятны. Одна из них - статические члены класса. Это одна из причин, почему я ими не пользуюсь. Мне не очень понятно, почему бы начальное присвоение стат-члену не сделать прямо в описании класса? И как вяжется присвоение ему значения в майне с тем, что он приватный? Хотя ясно, что это вопросы не к вам, а к Б.Страуструппу. Но я в повседневной практике стараюсь использования статических членов избегать.
DrOffset
7058 / 4199 / 949
Регистрация: 30.01.2014
Сообщений: 6,965
30.11.2014, 17:54     Ошибки LNK2001 и LNK1120 #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. Если детализированность ответа все еще неудовлетворительная, и что-то все равно не понятно, то спрашивай, я разверну еще. Давай добивать этот вопрос до конца
Байт
Эксперт C
15839 / 10166 / 1522
Регистрация: 24.12.2010
Сообщений: 19,166
30.11.2014, 18:18     Ошибки LNK2001 и LNK1120 #9
DrOffset, спасибо! Все вполне понятно. И пример на Си меня убедил окончательно (кстати, именно так я и поступаю) Мое предложение (о присвоение прямо в описании класса) вызвало бы еще одну заплатку в логике С++, а их там и без того хватает... Чисто эстетически и логически хотелось бы иметь такую возможность, но что делать, можно выбирать язык, но уж если выбрал - принимай его парадигмы!
Остался 1 маленький вопрос. Как "int Complex::s_count = 0;" согласуется с его приватностью? Ведь ни в одном из
методов, не являющихся методами класса Complex этого писать нельзя. А методах класса - просто глупо.
Или это просто пишется "сверху", вне функций? Когда-то я не смог выбраться из этого лабиринта, может быть получится сейчас?
DrOffset
7058 / 4199 / 949
Регистрация: 30.01.2014
Сообщений: 6,965
30.11.2014, 18:23     Ошибки LNK2001 и LNK1120 #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() // <------
{
//.....
}
Иными словами - это не доступ. Это операция разрешения области видимости, для определения функции. Со статической переменной ровно тоже самое.

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

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

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

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

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

Добавлено через 13 минут
DrOffset, Последний (надеюсь) вопрос. Вот я решил все статик-переменные класса инициализировать в одном месте. Статической функцией
C++
1
Complex::Init() { s_count = 0; }
ИМХО, этого не достаточно (опять линкер обидится). Нужно все равно где-то написать
C++
1
int Complex::s_count;
Так?
DrOffset
7058 / 4199 / 949
Регистрация: 30.01.2014
Сообщений: 6,965
30.11.2014, 19:14     Ошибки LNK2001 и LNK1120 #14
Цитата Сообщение от Байт Посмотреть сообщение
Так?
Да. Только задание значения в функции уже не будет инициализацией. Это будет присваивание.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
30.11.2014, 19:41     Ошибки LNK2001 и LNK1120
Еще ссылки по теме:

Найти причины и способы исправления ошибки "fatal error LNK1120: 1 неразрешенных внешних элементов" - C++
fatal error LNK1120: 1 неразрешенных внешних элементов Вот такая штука. Все уже делал.. В чем ошыбка? #include &lt;iostream&gt; #include...

LNK1120 - C++
Здравствуйте. Недавно начал изучать Visual C++ 2010. Создал пустой проект: #include &lt;iostream&gt; int mine() { std::cout &lt;&lt;...

LNK2019 and LNK1120 - C++
Помогите пофиксить 2 ошибки. Не могу понять что от меня требуется. Вот код программы: // det.cpp: определяет точку входа для консольного...

LNK2019 и LNK1120 - C++
Программа состоит из 3ех файлов: names.h #ifndef NAMES_H_ #define NAMES_H_ namespace SALES { const int QUARTERS = 4; struct...

Ошибка LNK1120 - C++
Здравствуйте! У проблема возникновения ошибки при инициализации: 1&gt;Тестируем все.obj : error LNK2019: ссылка на неразрешенный внешний...


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

Или воспользуйтесь поиском по форуму:
Jauhien41
0 / 0 / 0
Регистрация: 05.10.2014
Сообщений: 4
30.11.2014, 19:41  [ТС]     Ошибки LNK2001 и LNK1120 #15
Спасибо, теперь всё работает
Yandex
Объявления
30.11.2014, 19:41     Ошибки LNK2001 и LNK1120
Ответ Создать тему
Опции темы

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