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

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

Войти
Регистрация
Восстановить пароль
 
OrmaJever
9 / 9 / 0
Регистрация: 10.11.2011
Сообщений: 241
#1

Статические свойства классов - C++

03.04.2014, 18:41. Просмотров 954. Ответов 14
Метки нет (Все метки)

Есть класс со статическим свойством
C++
1
2
3
4
5
6
7
8
class Data
{
protected:
   static char *str, *newStr;
   static unsigned long writedBytes, curPos, strLen, i, flags;
   // ...
 
}
Я понимаю что статические свойства перед использованием нужно объявить, но где объявлять protected static?
Раньше у меня они были в паблике и я их объявлял просто вначале .cpp файла. Я пробовал их объявлять в методе init() который вызывается перед первым использованием
C++
1
2
3
4
5
void Data::init()
{
   char *Data::str, *Data::newStr;
   unsigned long Data::writedBytes, Data::curPos, Data::strLen, Data::i, Data::flags;
}
но тогда на каждое свойство кидало такую ошибку
Код
error: invalid use of qualified-name 'Data::str'
error: invalid use of qualified-name 'Data::newStr'
...
дак где же protected и private static объявлять?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.04.2014, 18:41
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Статические свойства классов (C++):

Статические свойства структур в заголовочных файлах - C++
Всем привет. Не могу найти в интернете инфу о том, как ведут себя статические свойства структур определённых в заголовочных файлах и...

Можно ли добавлять статические объекты классов в STL контейнеры? - C++
Или обязательно добавлять ссылки на них в контейнер? Нигде не могу найти ответа.

Двусмысленные свойства классов - C++
Всем доброго времени суток! Есть такая проблема. Пишу проект, подразумевающий наличие абстрактного класса, у которого наследуют свойства 2...

Разработать иерархию классов, демонстрирующее работу с коллекцией объектов разных классов - C++
Задание: Разработать в соответствии с индивидуальным заданием иерархию классов и приложение, демонстрирующее работу с коллекцией объектов...

Вынести методы из классов Panel и PictureBox (явная реализация методов базовых абстрактных классов) - C++
Тема: Множественное наследование. Явная реализация методов базовых абстрактных классов. Как вынести методы из классов Panel и...

Реализация отношения классов типа двунаправленная ассоциация, UML, порядок объявления классов, неполный класс - C++
Доброго времени суток! Осваивая UML, решил реализовать отношение двунаправленной ассоциации по диаграмме: У одного владельца...

14
dimcoder
Полярный
466 / 438 / 68
Регистрация: 11.09.2011
Сообщений: 1,136
03.04.2014, 18:58 #2
Цитата Сообщение от OrmaJever Посмотреть сообщение
дак где же protected и private static объявлять?
да там и объявлять, только обращаться к ним через статические методы.
Цитата Сообщение от OrmaJever Посмотреть сообщение
статические свойства перед использованием нужно объявить
по умолчанию инициализируются нулями кстати.
Цитата Сообщение от OrmaJever Посмотреть сообщение
но тогда на каждое свойство кидало такую ошибку
Цитата Сообщение от OrmaJever Посмотреть сообщение
unsigned long Data::writedBytes
это объявление о обращение в одном флаконе, вот и ошибка.
C++
1
unsigned long writedBytes
Вот это объявление (прошу заметить локальной переменной).
C++
1
Data::writedBytes
А вот это обращение к уже объявленной переменной.
1
OrmaJever
9 / 9 / 0
Регистрация: 10.11.2011
Сообщений: 241
03.04.2014, 19:08  [ТС] #3
Так, это я понял. Теперь такой вопрос, как к ним обращаться из текущего класса и из наследников?
0
alsav22
5421 / 4816 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
03.04.2014, 19:12 #4
Цитата Сообщение от OrmaJever Посмотреть сообщение
Я понимаю что статические свойства перед использованием нужно объявить,
Может инициализировать (определить)?
0
dimcoder
Полярный
466 / 438 / 68
Регистрация: 11.09.2011
Сообщений: 1,136
03.04.2014, 19:22 #5
Цитата Сообщение от OrmaJever Посмотреть сообщение
как к ним обращаться из текущего класса и из наследников?
Если public, то через имя класса и ::
C++
1
Data::writedBytes
В базовом классе можно напрямую, в наследнике только если public или protected.
а если private, то через методы .
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
#include <iostream>
#include <stdexcept>
 
class ClassA
{
    public:       
        int getX() const
        {
            return x;
        }
        
    private:
        static const int x = 10;
};
 
class ClassB: public ClassA
{
    public:
        void print() const
        {
            std::cout << getX() << std::endl;
        }
};
 
 
int main()
{
    ClassB b;
    b.print();
    return 0;
}
не компилил, могут быть ошибки.
1
OrmaJever
9 / 9 / 0
Регистрация: 10.11.2011
Сообщений: 241
03.04.2014, 19:29  [ТС] #6
хмм... вот ещё проблема вылезла, в Data есть protected метод
C++
1
Data &operator<< ( const char );
из наследника раньше (когда он был в паблике) обращался так
C++
1
*this << ...
а теперь пишет
Код
error: 'Data& Data::operator<<(char)' is protected
как тогда к нему обратиться ?
0
dimcoder
Полярный
466 / 438 / 68
Регистрация: 11.09.2011
Сообщений: 1,136
03.04.2014, 19:39 #7
Цитата Сообщение от OrmaJever Посмотреть сообщение
как тогда к нему обратиться ?
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
#include <iostream>
 
class ClassA
{        
    protected:
        static const int x = 10;
        
        ClassA& operator<<(const char c)
        {
            std::cout << "operator<<" << std::endl;
        }
};
 
class ClassB: public ClassA
{
    public:
        void print()
        {
            std::cout << x << std::endl;   //ClassA:: не обязательно
        }
        
        void doSmth()
        {
            (*this)<<'c';   //обращаемся
        }
};
 
 
int main()
{
    ClassB b;
    b.print();
    b.doSmth();
    return 0;
}
В наследнике все protected должны быть видны. Может унаследовать забыли, или тип наследование изменили с public на protected?
0
OrmaJever
9 / 9 / 0
Регистрация: 10.11.2011
Сообщений: 241
03.04.2014, 19:52  [ТС] #8
ладно если обращение через *this должно работать значит буду искать сам ошибку.
Цитата Сообщение от dimcoder Посмотреть сообщение
или тип наследование изменили с public на protected?
раз зашла за это речь можете мне объяснить какие бывают "типы наследования", и чем они отличаются? Я всегда использую public.
0
dimcoder
Полярный
466 / 438 / 68
Регистрация: 11.09.2011
Сообщений: 1,136
03.04.2014, 20:01 #9
Цитата Сообщение от OrmaJever Посмотреть сообщение
ладно если обращение через *this должно работать
можно без this
C++
1
2
3
4
void doSmth()
        {
            operator<<('c');
        }
Цитата Сообщение от OrmaJever Посмотреть сообщение
и чем они отличаются?
Если public, то все public остаются public, protected остаются protected, private остаются private.
Если protected, то все public становятся protected, protected становятся private, private остаются private.
Если private, то все public становятся private, protected становятся private, private остаются private.
1
OrmaJever
9 / 9 / 0
Регистрация: 10.11.2011
Сообщений: 241
03.04.2014, 20:40  [ТС] #10
ладно, с protected я могу понять, но private то зачем?? зачем наследовать класс без ничего (всё приватное), только ради типа ?
0
dimcoder
Полярный
466 / 438 / 68
Регистрация: 11.09.2011
Сообщений: 1,136
03.04.2014, 21:19 #11
Цитата Сообщение от OrmaJever Посмотреть сообщение
но private то зачем
protected, private наследование - это нечастое явление. Сам я его еще не использовал.
Цитата Сообщение от OrmaJever Посмотреть сообщение
зачем наследовать класс без ничего
не совсем так... public и protected методы будут так же доступны внутри наследника, но через наследника уже этот метод не позовешь т.к. он стал private. Пример лучше покажет
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
#include <iostream>
 
class ClassA
{
    public:
        void func1()
        {
            std::cout << "func1 calls func2" << std::endl;
            func2();
        }
        
    protected:
        void func2()
        {
            std::cout << "func2 calls func3" << std::endl;
            func3();
        }
        
    private:
        void func3()
        {
            std::cout << "func3 has been called" << std::endl;
        }
};
 
class ClassB: private ClassA
{
    public:
        void callFunc1()
        {
            std::cout << "b calls func1()" << std::endl;
            func1();
        }
};
 
class ClassC: public ClassA
{  
};
 
 
int main()
{
    ClassB b;
    ClassC c;
    b.callFunc1();
    //b.func1();   //error
    std::cout << "c calls func1()" << std::endl;
    c.func1();
    
    system("PAUSE>NULL");
    return 0;
}
b.func1() позвать нельзя, потому-что он стал private. А если наследовать через public, то можно было бы позвать, что c.func1() и доказывает.
Если говорить конкретно зачем оно надо - для композиции. Private наследование - это так называемое has-a наследование (один класс содержит другой как член. Пример: класс Машина содержит мотор), но не is-a(public наследование - это is-a) (машина - это не мотор). Мы можем обращаться к мотору через интерфейс - педали. Машина сама работает с мотором, водителю нужно знать только про педали. Так и здесь: main'y не надо знать про func1(), у него есть "педали" callFunc1(). Так почему бы просто не использовать композицию? Через композицию protected члены не будут видны, а через наследование будут.
Надеюсь, хоть что то да прояснилось.
PS Может эксперты пример получше приведут, уже с более реальной задачей.
1
OrmaJever
9 / 9 / 0
Регистрация: 10.11.2011
Сообщений: 241
04.04.2014, 18:22  [ТС] #12
Вопрос из первого поста мне всё таки решить не удалось. Закинул в protected статические свойства
C++
1
2
3
4
5
6
7
8
class Data
{
protected:
   static char *str, *newStr;
   static unsigned long writedBytes, curPos, strLen, i, flags;
   // ...
 
}
затем создал публичный статический метод init (в классе Data)
C++
1
2
3
4
5
void Data::init()
{
   char *str, *newStr;
   unsigned long writedBytes, curPos, strLen, i, flags;
}
он вызывается перед любым использованием этих свойств, но линковщик ругается
Код
undefined reference to `Data::strLen'
undefined reference to `Data::str'
...
почему он не находит их определения, и где оно должно быть?
0
dimcoder
Полярный
466 / 438 / 68
Регистрация: 11.09.2011
Сообщений: 1,136
04.04.2014, 19:05 #13
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
#include <iostream>
#include <iomanip>
 
class Data
{
    public:
        void init();
    protected:
        static char *str, *newStr;
        static unsigned long writedBytes, curPos, strLen, i, flags;
};
 
void Data::init()
{ 
    std::cout << "init" << std::endl;
   //char *str, *newStr;    //это просто объявление локальных переменных, но не инициализация
   //unsigned long writedBytes, curPos, strLen, i, flags;   //
}
 
int main()
{
    Data d;
    d.init();
        
    system("PAUSE>NULL");
    return 0;
}
Все компилится.
Я кажется понял что конкретно вы хотите сделать.
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
#include <iostream>
#include <iomanip>
 
class Data
{
    public:
        void init();
    protected:
        static char c;
        static char *str, *newStr;
        static unsigned long writedBytes, curPos, strLen, i, flags;
        
};
 
char Data::c = 'c';
unsigned long Data::writedBytes = 10;
 
class MoreData: public Data
{
    public:
        void doSmth()
        {
            std::cout << Data::c << std::endl << Data::writedBytes << std::endl;
        }   
};
 
int main()
{
    MoreData md;
    md.doSmth();
    system("PAUSE>NULL");
    return 0;
}
Если это не то, что я думая выложите Ваш код.
1
OrmaJever
9 / 9 / 0
Регистрация: 10.11.2011
Сообщений: 241
04.04.2014, 19:33  [ТС] #14
dimcoder, вы как-то в очередной раз угадали, я сделал как раньше, определение этих переменных просто вначале cpp файла и это заработало! Но я вообще не могу понять почему это работает??? Если свойство protected они не может быть видно за пределами класса и наследников, как может работать такая запись??
C++
1
2
3
4
5
6
7
8
class Data
{
    protected:
        static char *str, *newStr;
        static unsigned long writedBytes, curPos, strLen, i, flags; 
};
char *Data::str, *Data::newStr;
unsigned long Data::writedBytes, Data::curPos, Data::strLen, Data::i;
они ведь protected, мне такое даже в голову не пришло протестить.
Цитата Сообщение от dimcoder Посмотреть сообщение
Я кажется понял что конкретно вы хотите сделать.
Если вы про protected static то суть такая: Есть класс Data и несколько от него потомков (А, В, С), есть строка которую нужно обработать (по символьно), в зависимости от разных символов строку могут обрабатывать разные потомки (потомки не статические поэтому для обработки создаётся объект), например строка из 30 символов, 0-10 обрабатывает класс А, второй десяток класс С, третий класс В. И вот что бы все объекты работали с одной и той же строкой, позицией они должны быть статическим, а protected потому что к этой строке должны иметь доступ только потомки и недай бог изменить её из вне. Класс Data содержит общие служебные методы (для обработки строки) и вот эти статические свойства.
0
DrOffset
7313 / 4413 / 999
Регистрация: 30.01.2014
Сообщений: 7,247
04.04.2014, 21:07 #15
Цитата Сообщение от OrmaJever Посмотреть сообщение
Если свойство protected они не может быть видно за пределами класса и наследников, как может работать такая запись??
Его и не видно. А эта запись - это определение. По такому же принципу как с методами:
C++
1
2
3
4
5
6
7
8
9
10
11
class A
{
protected:
    void func(); // объявление
    static int var; //объявление
    static void func_static(); //объявление
};
 
void A::func() {} // определение (причем не обязательно в том же файле, главное что после типа А, т.е. А должно быть видно в месте определения)
int A::var = 10; // определение и инициализация
void A::static_func() { } // определение
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.04.2014, 21:07
Привет! Вот еще темы с ответами:

Преобразования объектов классов в объекты других классов - C++
Задача типа обмен валют. Нужно конвертировать старый фунт стерлинг(фунт, шиллинг и пенсы) в доллары и обратно, по курсу 1 фунт = 50...

Наследование классов. Копирование производных классов - C++
Здравствуйте всем, у меня такой вопрос: написал код #include &quot;stdafx.h&quot; class A //Создаем класс А { int mA; ...

статические массивы - C++
Дана ценлочисленная прямоугольная матрица. Определитть номер первого из столбцов, содержащих хотя бы один нулевой элемент. ...

Статические функции - C++
Начинаю изучать С++, написал код, но не хочет работать, подскажите, в чем может быть ошибка. class Sequence { public: Sequence(int...


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

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

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