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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.60
garjo_099
1 / 1 / 0
Регистрация: 08.04.2014
Сообщений: 31
#1

Классы.Ключевое слово static - выдает ошибку "неразрешенный внешний символ" - C++

09.04.2014, 00:39. Просмотров 1771. Ответов 23
Метки нет (Все метки)

Всем доброго времени суток.
Изучаю С++ по Шпаку и по урокам на сайте
Кликните здесь для просмотра всего текста
cppstudio.com
, предварительно хорошо ознакомившись с ассемблером...
Со всеми темами прорываюсь вперед без особых затруднений, дошел до изучения классов, начали появляться вопросы, вот решил найти себе пристанище для ответов.
По первому же запросу в гугле попал сюда =)
Ну да ладно...вообщем плохо разобрался со статической переменной static, точней понимаю, что она создаётся один раз, содержит последнее, внесённое в неё значение... а дальше, работа с классами и оператором расширения области действия :: очень запутался...

На данный момент вот такая проблема.

Visual studio 2013 выдаёт такие ошибки.

Мои догадки:
-из-за того, что интерфейс и реализация в одном файле...
-из-за компилятора, вставляю стандартный код, который был приведён для примера, выдаёт такие же ошибки.


Ошибка 1 error LNK2001: неразрешенный внешний символ ""private: static int AB::a" (?a@AB@@0HA)" C:\Users\garjo\Documents\Visual Studio 2013\Projects\Проект68\Проект68\Исходный код.obj Проект68

Ошибка 2 error LNK2001: неразрешенный внешний символ ""private: static int AB::b" (?b@AB@@0HA)" C:\Users\garjo\Documents\Visual Studio 2013\Projects\Проект68\Проект68\Исходный код.obj Проект68


Ошибка 3 error LNK1120: неразрешенных внешних элементов: 2 C:\Users\garjo\Documents\Visual Studio 2013\Projects\Проект68\Debug\Проект68.exe Проект68
при компиляции этого кода
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
#include <iostream>
 
using namespace std;
 
class AB //создаём класс 
{
private:
    static int a;
    static int b;
 
public:
    AB()
    {
        a = 1;
        b = 1;
        cout << "Тут сработал конструктор" << endl;//и здесь же их отобразим на экран
        cout << "a = " << a << endl;
        cout << "b = " << b << endl << endl;
    }
 
    void setAB()
    {
        cout << "Введите целое число а: ";
        cin >> a;
        cout << "Введите целое число b: ";
        cin >> b;
    }
 
    void getAB()
    {
        cout << "a = " << a << endl;
        cout << "b = " << b << endl << endl;
    }
 
    /*~AB() // это деструктор. не будем заставлять его чистить память, пусть просто покажет где он сработал
    {
        cout << "Тут сработал деструктор" << endl;
        system("pause");
 
    }*/
};
 
int main()
{
    setlocale(LC_ALL, "rus");
 
    AB obj1; //сработал конструктор
 
    obj1.getAB(); //для явной проверки
    obj1.setAB();   //присвоим новые значения переменным
    obj1.getAB();   //и выведем их на экран
 
    AB obj2;
    obj2.getAB;
    obj2.setAB;
    obj2.getAB;
 
    system("pause");
    return 0;
 
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.04.2014, 00:39
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Классы.Ключевое слово static - выдает ошибку "неразрешенный внешний символ" (C++):

Не могу убрать ошибку: "error LNK2001: неразрешенный внешний символ" - C++
здравствуйте весь интернет уже облазил , ни где похожего найти не могу . overview.obj : error LNK2001: неразрешенный внешний символ...

Исправить ошибку "LNK2019: ссылка на неразрешенный внешний символ _main в функции ___tmainCRTStartup" - C++
#include &quot;stdafx.h&quot; #include &quot;расчет.h&quot; #include &quot;conio.h&quot; #include &lt;windows.h&gt; #include &lt;commctrl.h&gt; #include &lt;iostream&gt; ...

Подскажите почему может появляться ошибка: "неразрешенный внешний символ "_SDL_..."" - C++
Привет всем =) Скажите пожалуйста почему у меня пишет: 1&gt;SDL.obj : error LNK2001: неразрешенный внешний символ &quot;_SDL_CreateCursor&quot; ...

Error LNK2019: "ссылка на неразрешенный внешний символ _main" - C++
1&gt;MSVCRTD.lib(crtexe.obj) : error LNK2019: ссылка на неразрешенный внешний символ _main в функции ___tmainCRTStartup ...

Циклы с выключателем и ошибка "ссылка на неразрешенный внешний символ" - C++
код такой получился main #include &lt;iostream&gt; #include &lt;conio.h&gt; #include &lt;stdio.h&gt; using namespace std; double...

Ошибка "LNK2019 ссылка на неразрешенный внешний символ" - C++
допустим есть файл A.h в котором записано следующее template &lt;typename T&gt; class A { public: A(); }; и есть файл A.cpp ...

23
AceOfSpades
44 / 43 / 3
Регистрация: 14.08.2012
Сообщений: 247
09.04.2014, 00:47 #2
Для статических переменных нужно делать разрешение символа, т.е. написать вне класса:

int AB::a;
int AB::b;

Т.к. по сути статические переменные не принадлежат классу.
Так что ваши догадки пока неверны)
1
DrOffset
7376 / 4453 / 1009
Регистрация: 30.01.2014
Сообщений: 7,304
09.04.2014, 00:59 #3
Цитата Сообщение от AceOfSpades Посмотреть сообщение
Т.к. по сути статические переменные не принадлежат классу.
Они принадлежат классу, но не принадлежат объекту.

garjo_099,
А необходимость вынесения определения переменных точно такая же, как необходимость определения объявленных в классе функций. То есть семантически вот эти записи связаны:
C++
1
2
3
4
5
6
7
8
9
10
11
class A
{
public:
    void f(); // объявление
    static int a; // объявление
    static void fs(); // объявление
};
 
int A::a = 0; //определение
void A::f() {} //определение
void A::fs() {} //определение
0
alsav22
5426 / 4821 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
09.04.2014, 01:11 #4
garjo_099, под поля класса, память, при объявлении класса, не выделяется. Память под них выделяется при создании объектов класса, но так как статические переменные класса не принадлежат объектам, то память под них необходимо выделить отдельно (определить эти переменные вне класса).
0
anonymous_
6 / 6 / 1
Регистрация: 21.11.2013
Сообщений: 22
09.04.2014, 01:17 #5
статические классы члены и методы класса относяться к классу в целом, а не к отдельному объекту

статический член класса существует в единственном экземляре, независимо оттого, созданы ли объекты класса и сколько

статический метод класса можно вызвать, даже если нет ни одного экземпляра класса ( допустим у тебя в классе дата есть такой метод getCurrentDate но если он не статический то что бы допустим узнать текущию дату тебе нужно создать объект в мейне ну вот такие вещи и делают статикой что бы не создавать объект)

C++
1
cout << "Today is " << Date::getCurrentDate() << endl;
если не статикой то нужно в мейне создавать объект
зачем нам нужно объявлять переменные типа дата если мы просто хотим узнать текущую дату
C++
1
2
Date d;
cout << "Today is " << d.getCurrentDate() << endl;
0
AceOfSpades
44 / 43 / 3
Регистрация: 14.08.2012
Сообщений: 247
09.04.2014, 01:59 #6
Цитата Сообщение от DrOffset Посмотреть сообщение
Они принадлежат классу, но не принадлежат объекту.
Не совсем так. Возможно я неправильно выразился.

Статические данные класса по сути - глобальные переменные с видимостью в namespace класса.
Статические члены данных не является частью объектов заданного типа класса; они отдельные объекты. В результате объявление статического члена данных не является определением. Элемент данных объявлен в области класса, но определение выполняется в области файла.
Как-то так.
0
DrOffset
7376 / 4453 / 1009
Регистрация: 30.01.2014
Сообщений: 7,304
09.04.2014, 08:24 #7
Цитата Сообщение от AceOfSpades Посмотреть сообщение
Не совсем так.
Storage duration и принадлежность чему-либо в С++ понятия независимые. Если нечто объявлено внутри функции - оно принадлежит функции. Если нечто объявлено внутри namespace - оно принадлежит namespace. Если нечто объявлено внутри класса - оно принадлежит классу, в частности доступ к static полям все так же разрешается спецификаторами доступа. Так что мое определение вполне верное.

Цитата Сообщение от AceOfSpades Посмотреть сообщение
Статические члены данных не является частью объектов заданного типа класса
Именно об этом я и написал и про определение и объявление тоже.
0
garjo_099
1 / 1 / 0
Регистрация: 08.04.2014
Сообщений: 31
09.04.2014, 16:36  [ТС] #8
переделал код, и он показывает, что переменная в каждом экземпляре класса (при создании большого количества объектов класса) хранит последние внесённые в неё данные.
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
#include <iostream>
 
using namespace std;
 
class AB //создаём класс 
{
private:
    static int a;
    static int b;
 
public:
    AB()
    {
        cout << "Тут сработал конструктор" << endl;//и здесь же их отобразим на экран
        cout << "a = " << a << endl;
        cout << "b = " << b << endl << endl;
    }
 
    void setAB()
    {
        cout << "Введите целое число а: ";
        cin >> a;
        cout << "Введите целое число b: ";
        cin >> b;
    }
 
    void getAB()
    {
        cout << "a = " << a << endl;
        cout << "b = " << b << endl << endl;
    }
 
    /*~AB() // это деструктор. не будем заставлять его чистить память, пусть просто покажет где он сработал
    {
        cout << "Тут сработал деструктор" << endl;
        system("pause");
 
    }*/
};
 
int AB::a;
int AB::b;
 
int main()
{
    setlocale(LC_ALL, "rus");
 
    AB obj1; //сработал конструктор
 
    obj1.getAB(); //для явной проверки
    obj1.setAB();   //присвоим новые значения переменным
    obj1.getAB();   //и выведем их на экран
 
    AB obj2;
    obj2.getAB();
    obj2.setAB();
    obj2.getAB();
 
    system("pause");
    return 0;
 
}
Добавлено через 3 минуты
anonymous_, ага спасибо, вроде немножко разтуманилось.

Добавлено через 4 минуты
И ещё вопрос. Из-за чего лучше объявлять определение за интерфейсом класса???
0
AceOfSpades
44 / 43 / 3
Регистрация: 14.08.2012
Сообщений: 247
09.04.2014, 16:44 #9
Цитата Сообщение от garjo_099 Посмотреть сообщение
И ещё вопрос. Из-за чего лучше объявлять определение за интерфейсом класса???
Не просто за интерфейсом, а лучше в отдельном cpp файле. Почитайте про раздельную компиляцию. Когда есть h-файл и его реализация в cpp-файле можно конечному пользователю поставлять только интерфейс в h-файле и скомпилированный cpp-файл, т.е. не выдавать исходные коды.
0
garjo_099
1 / 1 / 0
Регистрация: 08.04.2014
Сообщений: 31
09.04.2014, 20:09  [ТС] #10
Подскажите алгоритм как реализовать, ввод даты допустим, через точку в формате дд.мм.гггг

Добавлено через 9 минут
Через разбор строки наверное будет самый простой способ...

Добавлено через 42 минуты
а точней преобразовать строку дд.мм.гггг в числа и разбить в структуру или по отдельным переменным без точки.
0
DrOffset
7376 / 4453 / 1009
Регистрация: 30.01.2014
Сообщений: 7,304
09.04.2014, 20:11 #11
garjo_099, scanf такое может
0
garjo_099
1 / 1 / 0
Регистрация: 08.04.2014
Сообщений: 31
09.04.2014, 20:33  [ТС] #12
от примера не отказался бы =)))
0
DrOffset
7376 / 4453 / 1009
Регистрация: 30.01.2014
Сообщений: 7,304
09.04.2014, 21:12 #13
Цитата Сообщение от garjo_099 Посмотреть сообщение
от примера не отказался бы =)))
C++
1
2
3
4
5
6
7
8
9
10
11
#include <cstdio>
 
int main()
{
    int d = 0, m = 0, y = 0;
    if(scanf("%2d.%2d.%4d", &d, &m, &y) == 3)
    {
        printf("%d.%d.%d\n", d, m, y);
    }
    return 0;
}
0
garjo_099
1 / 1 / 0
Регистрация: 08.04.2014
Сообщений: 31
10.04.2014, 01:34  [ТС] #14
Написал код, только сильно не пинайте и громко не смейтесь=)) программка чисто для практики, писал код собственными алгоритмами, построенные в моей голове на основе того, что знаю на данный момент, никуда не подглядывая. Вообщем цель перевести строку даты в целочисленные тип данных. Помогите найти ошибки, с функцией, что-то не так и с оператором gets в main функции, не запрашивает повторный ввод, код компилится но выдаёт ошибку.

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
#include <iostream>
 
using namespace std;
 
bool preobrazStroki(char *); //прототип функции которая преобразует строку в символы
 
struct day
{//вообщем глобальные переменные для хранения отработаных результатов
    static char a, b;
};
struct mm
{
    static char a, b;
};
struct year
{
    static char a, b, c, d;
};
 
char day::a, day::b;
char mm::a, mm::b;
char year::a, year::b, year::c, year::d;
 
int main()
{
    setlocale(LC_ALL, "rus");
 
    char currentdate[11];//строка куда будем записывать дату
    bool stop = true;//переменная для условия выхода из цикла while
    //char *ptrcurrentdate = &currentdate[11];
    while (stop == true)
    {
        cout << "Введите дату в формате дд.мм.гггг" << endl;
 
        gets_s(currentdate);//считываем символы с клавиатуры в строку  п.с.и почему-то при повторном запуске цикла не запрашивает ввод данных
 
        char *ptrcurrentdate = &currentdate[11]; //так и не определился где лучше создать указатель вне цикла или внутри цикла...
        cout << ptrcurrentdate << endl;//для проверки, но выпуливает какой-то шлак(((
 
        if (currentdate[2] == '.' && currentdate[5] == '.')// первые условия правильности ввода даты
        {
            if (preobrazStroki(ptrcurrentdate))//если функция вернёт тру
            {
                int day1 = day::a - '0', day2 = day::b - '0', mm1 = mm::a - '0', mm2 = mm::b - '0';//конечные переменные с которымы
                //в будущем можно будет работать и вычислять количество дней с вашего дня рождения =))))
                int yy1 = year::a - '0', yy2 = year::b - '0', yy3 = year::c - '0', yy4 = year::d - '0';
                cout << day1 << day2 << "." << mm1 << mm2 << ".";//печать даты уже в формате int
                cout << yy1 << yy2 << yy3 << yy4 << endl;
            }
        }
        else
        {
            cout << "Неверный формат даты, вводите в таком формате дд.мм.гггг!\n";
            cout << "Если желаете продолжить нажмите 1, если хотите выйти, нажмите 0\n";//тут всё понятно я думаю
            cin >> stop;
 
        }
 
    }
 
 
    system("pause");
    return 0;
}
 
bool preobrazStroki(char *value)
{
    //day day1;
    //mm mm1;
    //year year1;
    
    while (*value != '\0')//пока указатель не будет указывать на asciiz
    {//собственно сама функция и с ней что-то не то.
        if (isdigit(*value))//если все if сработают функция вернёт true и дата запишется в глобальные переменные 
        {
            day::a = *value;
            value++;
        }
        else
        {
            cout << "neverniu format" << endl;
            break;//было задумано, если программа находит какой-то символ, а не цифру, то функция возвращает false
        }
 
            if (isdigit(*value))
            {
 
                day::b = *value;
                value += 2;
            }
            else
            {
                cout << "neverniu format" << endl;
                break;
            }
            if (isdigit(*value))
            {
 
                mm::a = *value;
                value++;
            }
            else
            {
                cout << "neverniu format" << endl;
                break;
            }
            if (isdigit(*value))
            {
                mm::b = *value;
                value += 2;
            }
            else
            {
                cout << "neverniu format" << endl;
                break;
            }
            if (isdigit(*value))
            {
 
                year::a = *value;
                value++;
            }
            else
            {
                cout << "neverniu format" << endl;
                break;
            }
            if (isdigit(*value))
            {
 
                year::b = *value;
                value++;
            }
            else
            {
                cout << "neverniu format" << endl;
                break;
            }
 
            if (isdigit(*value))
            {
            year::c = *value;
                value++;
            }
            else
            {
                cout << "neverniu format" << endl;
                break;
            }
    
            if (isdigit(*value))
            {
                year::d = *value;
                value++;
            }
            else
            {
            cout << "neverniu format" << endl;
            break;
            }
            return true;
    }
    return false;
}
0
alsav22
5426 / 4821 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
10.04.2014, 02:14 #15
Цитата Сообщение от garjo_099 Посмотреть сообщение
не запрашивает повторный ввод
C++
1
(cin >> stop).get();
0
10.04.2014, 02:14
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.04.2014, 02:14
Привет! Вот еще темы с ответами:

Ошибка "ссылка на неразрешенный внешний символ _main" - C++
&gt;MSVCRTD.lib(crtexe.obj) : error LNK2019: ссылка на неразрешенный внешний символ _main в функции ___tmainCRTStartup ...

Error LNK2001: неразрешенный внешний символ "_main" - C++
1&gt;MSVCRT.lib(crtexe.obj) : error LNK2001: неразрешенный внешний символ &quot;_main&quot; Что это такое и как его убрать?

Класс "Зачетка": Ссылка на неразрешенный внешний символ - C++
Практиковался( Visual Studio 2012) в написании программы и выдаёт вот такую ошибку 1&gt;MSVCRTD.lib(crtexe.obj) : error LNK2019: ссылка на...

Обработка ошибок "Ссылка на неразрешенный внешний символ" - C++
взял код из сети по работе с WinPCap. откомпилить его не могу. ошибки валятся. появляются только в тот момент когда со всеми error'ами...


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

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

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