Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1] 2  Все   Вниз
  Печать  
Автор Тема: Задача про класс: сколько ошибок?  (Прочитано 35110 раз)
0 Пользователей и 5 Гостей смотрят эту тему.
Olegator
Команда клуба

ru
Offline Offline
Пол: Мужской

« : 01-04-2005 20:22 » 

В учебнике есть задача. Сколько ошибок обнаружит компилятор в следующем коде?
Код:
1. class Ping {
2. public:
3.     Ping() const {};
4.     Ping(int _x) { x = _x; };
5.     int SetX(int _x) const { x = _x; };
6.     const int GetX(int _x) const { return x; };
7. private:
8.     int x;
};
Варианты ответа: 1 2 3 4 5 ошибок.
Наверное, имеется в виду только ошибки компиляции.
В ВС++ вышло 2 ошибки.
Error NONAME00.CPP 3: constructor cannot be declared 'const' or 'volatile'
Error NONAME00.CPP 5: Cannot modify a const object
Что это значит.
И не могли бы вы написать комментарии к каждой строке.
« Последнее редактирование: 17-12-2007 16:55 от Алексей1153++ » Записан
Alf
Гость
« Ответ #1 : 01-04-2005 20:51 » 

Error NONAME00.CPP 3: constructor cannot be declared 'const' or 'volatile'

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

Error NONAME00.CPP 5: Cannot modify a const object

Опять попытка изменить состояние класса, а именно - его переменной x. Метод, объявленный как const, не имеет право менять ни одну из переменных-членов класса.

И не могли бы вы написать комментарии к каждой строке.

Изволь:
Код:
1. class Ping { // начало объявления класса
2. public: // открытые члены класса
3.   Ping() const {}; // метод без аргументов, не возвращающий значения, с именем класса является конструктором по умолчанию
4.   Ping(int _x) { x = _x; }; // конструктор с одним аргументом, задающим значение переменной x;
    // не самый лучший вариант. Корректнее было бы: Ping(int _x): x(_x) { };
    // подробно об инициализации я писал в обсуждении одной из статей Михалыча, посмотри там,
    // не хочу повторяться
5.   int SetX(int _x) const { x = _x; }; // метод для изменения состояния переменной x;
    //  как уже был сказано, слово [b]const[/b] здесь явно лишнее
6.   const int GetX(int _x) const { return x; }; // метод для чтения скрытой переменной класса x
7. private: // скрытые члены класса
8.   int x; // целочисленная переменная, к которой имеют доступ лишь члены класса Ping
}; // завершение объявления класса - обрати внимание на точку с запятой в конце, она необходима
« Последнее редактирование: 17-12-2007 16:56 от Алексей1153++ » Записан
Olegator
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 01-04-2005 22:08 » 

В чём разница вот с этим кодом:
Код:
// определение класса комплексных чисел
class Complex
{
public:
   int real; // вещественная часть
   int imaginary; // мнимая часть
   // прибавить комплексное число
   Complex operator+(const Complex x) const;
};

Во-первых, этот метод возвращает значение типа Complex
(операция сложения в результате дает новое значение того же типа, что и типы операндов).
Во-вторых, перед аргументом метода появилось ключевое слово const.
Это слово обозначает, что при выполнении данного метода аргумент изменяться не будет.
Также const появилось после объявление метода. Второе ключевое слово const означает, что объект,
выполняющий метод, не будет изменен.
При выполнении операции сложения x + y над двумя величинами x и y сами эти величины не изменяются.
Этот код преподносится как правильный
Записан
Alf
Гость
« Ответ #3 : 01-04-2005 22:17 » 

А он и есть совершенно правильный (чем и отличается от первого). Хотя, конечно, для полноценного класса не мешало бы конструктор добавить и операторов побольше определить. Но для учебных целей пойдет.

Кстати, ты статьи Михалыча читал? Он ведь в основном очень толково и подробно эту тему разъяснил.
Записан
narco2005
Гость
« Ответ #4 : 05-08-2005 17:41 » 

хочу из класса c2 вызывать m_func  но так и не понял что здесь не так
может есть способ проще
class c1{
public:
c1(){};
void M_func(int l){l++;};
};


class c2{
friend void c1::M_func(int l);
public:
int i;

void main_f(){
c1::M_func(i);
};
};
Записан
Alf
Гость
« Ответ #5 : 05-08-2005 20:51 » 

1. Метод M_func класса c1 является открытым, поэтому для доступа к нему не требуется объявление друга.

2. Если хочешь вызывать метод, не создавая экземпляр класса, нужно сделать его методом класса, т.е. объявить как static.
Записан
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 11-08-2005 15:40 » 

Цитата
2. Если хочешь вызывать метод, не создавая экземпляр класса, нужно сделать его методом класса, т.е. объявить как static.
В книге Герберта Шилдта (издание 4), я читал, что статический метод класса может обращаться (работать) только со статическими переменными, а переменная i статической не является, получается ошибка тогда? Или я не прав?
Записан

ещё один вопрос ...
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #7 : 11-08-2005 16:06 » 

nikedeforest, конечно - ошибка компиляции. Нельзя доступиться до того, что может не существовать вообще или быть в множественом числе.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Alf
Гость
« Ответ #8 : 11-08-2005 20:48 » 

В книге Герберта Шилдта (издание 4), я читал, что статический метод класса может обращаться (работать) только со статическими переменными, а переменная i статической не является, получается ошибка тогда? Или я не прав?

Не прав. Либо у Шилдта такого не написано, либо он имел в виду что-то другое.

Любой метод (в том числе и статический) может обращаться к любым переменным, которые находятся в его области видимости. А это не только статические переменные класса, к которому принадлежит метод, но и глобальные, и формальные параметры метода, и его локальные переменные... (короче, долго перечислять).

В данном случае статический метод c1::M_func(i) получает копию значения переменной i через стек. Никаких ошибок ни при компиляции, ни при выполнении и близко не должно быть, у тебя сигнатура вызова полностью совпадает с сигнатурой определения метода.

Другое дело, если ты надеешься, что после вызова метода значение переменой i станет на единицу больше, то этим надеждам не суждено сбыться. Но это уже другая тема, а с точки зрения формального синтаксиса тут все в порядке.
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #9 : 11-08-2005 21:10 » 

Вот код для пробы
Код:
class myprob
{
public:
myprob(int _i);
static int Geti(void);
private:
int i;
};
myprob::myprob(int _i)
{
i = _i;
}

int myprob::Geti(void)
{
return i;
}

int main()
{
myprob my(5);
int q=my.Geti();
        return 0;
}
Alf Компилятор VC++ 6 дал такую ошибку:
Цитата
E:\C++\Probclass\Main.cpp(16) : error C2597: illegal reference to data member 'myprob::i' in a static member function
« Последнее редактирование: 17-12-2007 16:57 от Алексей1153++ » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Alf
Гость
« Ответ #10 : 11-08-2005 21:16 » 

Finch, гляди внимательнее. У тебя совсем другой случай. Переменную-член класса трогать действительно нельзя.
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #11 : 11-08-2005 21:34 » 

Альф извиняюсь, я прочитал мысль nikedeforest и не обратил внимание на пример. Жаль
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
kasper
Гость
« Ответ #12 : 12-08-2005 00:33 » 

Olegator:
В чём разница вот с этим кодом:
Код:
// определение класса комплексных чисел
class Complex
{
public:
   int real; // вещественная часть
   int imaginary; // мнимая часть
   // прибавить комплексное число
   Complex operator+(const Complex x) const;
};

Во-первых, этот метод возвращает значение типа Complex
(операция сложения в результате дает новое значение того же типа, что и типы операндов).
Во-вторых, перед аргументом метода появилось ключевое слово const.
Это слово обозначает, что при выполнении данного метода аргумент изменяться не будет.
Также const появилось после объявление метода. Второе ключевое слово const означает, что объект,
выполняющий метод, не будет изменен.
При выполнении операции сложения x + y над двумя величинами x и y сами эти величины не изменяются.
Этот код преподносится как правильный

В данном случае лучше объявить переменные-члены как private.
A все остальное как public.
Еще нужен конструктор (это если ты захочешь изменить переменные-члены, инициализировав их новыми значениями. Естественно const сдесь, совершенно ни к чему.

class Complex
{
public: 
     Complex(int, int);
     Complex operator+(const Complex x) const;
private:
     int real;
     int imaginary;
};

P.S. Я вообще не пойму, const нужен ли где-нибудь вообще, кроме начальных установок системы
Да, и объясните, пожалуйста, что значит нижняя черточка перед 'x':
Ping(int _x) { x = _x; };
« Последнее редактирование: 17-12-2007 16:58 от Алексей1153++ » Записан
Hooter
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #13 : 12-08-2005 05:01 » 

В данном случае лучше объявить переменные-члены как private.
A все остальное как public.
Еще нужен конструктор (это если ты захочешь изменить переменные-члены, инициализировав их новыми значениями. Естественно const сдесь, совершенно ни к чему.

class Complex
{
public: 
     Complex(int, int);
     Complex operator+(const Complex x) const;
private:
     int real;
     int imaginary;
};

Проблема стиля, ИМХО. Какая разница, как будет выглядеть получение мнимой части комплексного числа, так
Код:
Complex a(1, 1);
int x = a.imaginary;
или так
Код:
Complex a(1, 1);
int x = a.imaginary();
, кроме того, что во втором варианте тебе нужно засунуть real и imaginary в секцию private и определить методы получения и изменения этих переменных.

Другое дело, если получение мнимой части связано с какими-то вычислениями или зависит от вычислений в других потоках... Но мы же пока о нормальных комплексных числах говорим. Улыбаюсь

Так что прятать real и imaginary в этом классе - далеко не лучший вариант. Повальная инкапсуляция не всегда приводит к добру Ага Читай Мейерса.

P.S. Я вообще не пойму, const нужен ли где-нибудь вообще, кроме начальных установок системы

А конст здесь нужен для того, чтобы информировать компилятор и пользователя о том, что operator+ класса Complex не изменяет состояние класса. Этот оператор можно безболезненно вызывать в других константных методах класса Complex. В таком виде класса, как сейчас (всего один метод определен), действительно значения не имеет. Но мало ли для чего может понадобиться в дальнейшем...

Имхо, конст правильно стоит - метод же действительно не меняет состояние класса. Опять же, Мейерса читай Ага

Хотя я бы вынес оператор+ в отдельную функцию, а не делал бы ее методом класса. Но это кому как нравится..

Да, и объясните, пожалуйста, что значит нижняя черточка перед 'x':
Ping(int _x) { x = _x; };

Она здесь для того, чтобы не было конфликта имен - класс Ping тоже ведь имеет переменную-член x.
Представь, что скажет компилятор, увидев следующее:
Код:
Ping (int x)
{
    x = x;
}
Что он (компилятор) должен присваивать и кому?
Можно быто просто использовать другое имя:
Код:
Ping (int v)
{
    x = v;
}
« Последнее редактирование: 17-12-2007 17:02 от Алексей1153++ » Записан
Alf
Гость
« Ответ #14 : 12-08-2005 06:20 » 

...
Еще нужен конструктор (это если ты захочешь изменить переменные-члены, инициализировав их новыми значениями. Естественно const сдесь, совершенно ни к чему.

Конструктор вызывается только в момент создания нового экземпляра класса. Существующие объекты с его помощью изменять нельзя. Тут уж придется либо оснащать класс методами-мутаторами, либо определять для него оператор присваивания (либо и то, и другое).

...
Да, и объясните, пожалуйста, что значит нижняя черточка перед 'x':
Ping(int _x) { x = _x; };

Всего лишь еще одна буква. Правда, злолупотреблять ей не следует, ибо идентификаторы, начинающиеся с литеры '_', обычно используются самим компилятором и библиотеками, так что нужно соблюдать осторожность, дабы не нарваться на коллизию имен.
« Последнее редактирование: 17-12-2007 17:07 от Алексей1153++ » Записан
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #15 : 12-08-2005 11:34 » 

Цитата
Любой метод (в том числе и статический) может обращаться к любым переменным, которые находятся в его области видимости. А это не только статические переменные класса, к которому принадлежит метод, но и глобальные, и формальные параметры метода, и его локальные переменные... (короче, долго перечислять).
Цитата
Переменную-член класса трогать действительно нельзя.
Это мое заблуждение. Я думал что статический метод может работать только со статическими полями класса. Но как я понял, он может и работать с другими переменными (внутри себя) и с глобальными, но не с полями класса, если эти поля не статические.  Теперь я правильно понял?
Записан

ещё один вопрос ...
kasper
Гость
« Ответ #16 : 12-08-2005 21:32 » 

thank you big, for you answer
Записан
Alf
Гость
« Ответ #17 : 12-08-2005 21:38 » 

Я так понимаю, тут есть одна тонкость, которая может сбить с толку. С одной стороны, в самом деле:

Цитата
Переменную-член класса трогать действительно нельзя.

При этом имеется в виду, что ее нельзя "трогать" непосредственно. Например, так (пример похищен у Finch'а с добавлением моих комментариев):

Вот код для пробы
Код:
class myprob
{
public:
myprob(int _i);
static int Geti(void);
private:
int i;
};
myprob::myprob(int _i)
{
i = _i;
}

int myprob::Geti(void)
{
return i; // грубая ошибка - статическая функция-член класса ссылается на переменную-член класса;
// компилятор не в состоянии определить, переменную-член i какого именно экземпляра класса
// использовать для возврата значения.
}

int main()
{
myprob my(5);
int q=my.Geti();
 return 0;
}
Alf Компилятор VC++ 6 дал такую ошибку:
Цитата
E:\C++\Probclass\Main.cpp(16) : error C2597: illegal reference to data member 'myprob::i' in a static member function

Разумеется, компилятор выразил свое недовольство такой конструкцией, не имея возможности сгенерировать корректный код (если бы даже сгенерил, он бы не имел никакого смысла по указанной причине).

С другой стороны, возьмем код narco2005 (с небольшими исправлениями):
Код:
class c1
{
public:
  c1(){};
  static void M_func(int l){l++;};
};


class c2
{
public:
  int i;

  void main_f() { c1::M_func(i); };
};

Казалось бы, статическая функция c1::M_func(i) обращается к переменной-члену i класса c2, поэтому такая конструкция недопустима. Однако на самом деле функция main_f() является членом класса c2 и по этой причине знает значение переменной i, а следовательно, может передать его как аргумент функции c1::M_func(i). Та, в свою очередь, не имеет никакого представления о том, что данное значение на самом деле принадлежит переменной-члену класса; она лишь снимает со стека значение и выполняет с ним предписанные действия, как и с любой другой переменной. К слову сказать, переменная i в данном примере не обязана быть открытой, ибо main_f() имеет доступ ко всем членам класса  c2.

Итак, чтобы избежать подобной путаницы, я бы немного изменил правило таким образом: статическая функция-член класса не должна непосредственно обращаться к переменным-членам класса.
« Последнее редактирование: 17-12-2007 17:08 от Алексей1153++ » Записан
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #18 : 13-08-2005 10:18 » 

Вполне понятно, но чувствую, что я даже ума не могу приложить, где может применяться статический метод класса (чтобы от этого применения польза была, а не ради примера). Я вижу что на статический метод класса накладываются дополнительные ограничения (по сравнению с обычным методом), но при этом с помощью статического метода нельзя ничего сделать такого, что не позволял бы сделать обычный метод класса (витеевато наверное написано). Вижу только одно применение - это непосредственная работа со статическими полями класса, хотя с ними может работать и обычным метод класса. Тогда что же? Подкиньте какую-нибудь идейку из жизни.
Записан

ещё один вопрос ...
Михалыч
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #19 : 13-08-2005 14:49 » new

Когда-то давно, помнится я проглядывал книгу - что-то типа "С++ для чайников" и там как раз приводилась идея - зачем...
Ну, что-то, если память мне не изменяет - есть, допустим, класс УТКА. Тогда функция "летать" будет относиться к каждому конкретному ОБЪЕКТУ класса, т.е. с определенной уткой. А более общая функция "вымирание" связана уже со всем утиным племенем "в целом" т.е. с классом вообще. Ее-то и имеет смысл сделать статической...
Т.е. статические функции удобны, когда  некое действие связано не с отдельным объектом а с классов "в целом".
Записан

Поживем - увидим... Доживем - узнаем... Выживу - учту  Улыбаюсь
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #20 : 13-08-2005 14:55 » 

Но ведь все равно в этом случае можно заменить статическую функцию-член класса на обычную и при этом мы теряем только возможность обращаться к этому методу на прямую, т.е.
<class name>::<имя функции>.
Я думаю, может я чего не знаю по поводу преимуществ и недостатков(в смысле ограничения). Т.е. я знаю что к статическому методу класса можно обратиться напрямую (как указано выше), к обычному методу класса так обращаться нельзя. Больше из того что может статический метод и не может не статический я незнаю. Знаю ограничения статического метода (мы их выше обсудили) и этих ограничений явно больше чем у не статического. Пока я делаю вывод, что статический метод применяется очень редко и  в любом случае не может сложиться такой ситуации в которой статический метод делает что-то такое чего нельзя было бы достичь с помощью неситатического метода.
Единственное, если мы желаем того,чтобы метод обладал ограничениями которыми обладает статический метод, то тогда да.
« Последнее редактирование: 13-08-2005 15:10 от nikedeforest » Записан

ещё один вопрос ...
Alf
Гость
« Ответ #21 : 13-08-2005 18:30 » 

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

Вот тебе вполне реальный пример.

В данный момент я работаю над программной моделью довольно крупной телефонной станции. Эта модель должна прояснить ряд моментов, в том числе - помочь произвести оптимизацию маршрутов телефонных звонков (по различным критериям, в том числе - минимизация стоимости). Для этого в первую очередь необходимо иметь данные о конфигурации станции, которая описывается на специальном языке. Беда в том, что распечатка управляющей программы занимает под тысячу листов, и разобраться в ней оператору не представляется возможным. Поэтому было решено произвести программное моделирование станции, и эту работу поручили мне.

Для ввода данных в модель мне потребовалось разработать компилятор языка программирования станции. Каждая конструкция считывается из входного файла, анализируется, псле чего информация заносится в соответствующие таблицы. Затем можно моделировать работу станции, пользуясь информацией из этих таблиц.

Разумеется, у каждого оператора свой собственный синтаксис. Я решил для каждого оператора создать отдельный класс, инкапсулирующий все параметры данного оператора. Поэтому в программе имеется абстрактный класс "оператор", от которого наследуют конкретные классы, например, CodePoint. Каждый конкретный класс "знает", каким образом считать свое тело из входного файла. Причем единственный способ получить экземпляр класса - это разобрать часть входного файла, других способов не должно быть. Схематически это можно представить так:

Код:
public abstract class Oper
{
  protected Oper(...) { ... }
  public static Oper Parse(InFileStream ifs)
  {
    ...
    Oper op;
    ...
    // текущий оператор - CodePoint
    op = CodePoint.Parse(ifs);
    ...
    return op;
  }
  ...
}

public class CodePoint: Oper
{
  protected CodePoint(...): base(...) { ... }
  public static CodePoint ParseCodePoint(InFileStream ifs) { ... }
  ...
}

Если посмотришь повнимательнее на класс CodePoint, заметишь, что его конструктор защищен, т.е. виден только членам самого класса CodePoint и производных от него классов. Глобально конструктор не виден. А это значит, что создать экземпляр класса CodePoint конструкцией вроде
Код:
CodePoint cp = new CodePoint(...);
не получится, возникнет ошибка компиляции. Единственный способ получить экземпляр  CodePoint, как я уже говорил, - разобрать входной файл. Для этого служит статический метод ParseCodePoint, который создает объект типа CodePoint и возвращает его как результат функции. Этот метод может вызвать защищенный конструктор, поскольку конструктор находится в его области видимости. Итак, эта конструкция работает:
Код:
CodePoint cp = CodePoint.ParseCodePoint(ifs);

Такой подход позволяет избежать потенциальных ошибок, не позволяя создавать экземпляры CodePoint некорректным образом через new, а также улучшает качество программы за счет соответствия шаблону GRASP High Cohesion.

Я полагаю, если дочитал до этого места, то уже понятно, что другим способом, кроме введения статической функции, я бы эту задачу не решил. Ведь метод ParseCodePoint выдает экземпляр CodePoint, который до этого не существовал, поэтому нестатический метод не может быть вызван в принципе.
Записан
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #22 : 14-08-2005 18:15 » 

Я когда по началу увидил защищенный конструктор, то подумал, что брежу Улыбаюсь.  Пример изысканный и здесь используется единственное преимущество статического метода перед нестатическими (вызов на прямую).
Не сочтите за наглость, но можно еще один прмерчик, но только такой в котором за основу использования статического метода берется не свойство вызова на прямую, а что-то другое.
зы: вы не подумайте, что я прмер Альфа не понял, я его понял и он мне очень понравился, но в нем используется единственное преимущество статического метода перед нестатическим. Хотелось бы увидеть использование нестатич. функций по другим соображениям.
Записан

ещё один вопрос ...
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #23 : 14-08-2005 18:30 » 

Косвенное использование свойств статических функций. Это функции обратного вызова, которые используются в системе. Так как статическая функция  не привязана к конкретному экземпляру класса, следовательно в функцию не передается ссылка на данный экземпляр. И функция может поддерживать стандарт CALLBACK.
Код:
#include <iostream.h>
#include <windows.h>

class Enum
{
public:
Enum(void);
void Run(void);
void Print(HWND hwnd);
private:
static BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam);
int i;

};

Enum::Enum(void)
{
i=0;
}

BOOL CALLBACK Enum::EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
  ((Enum *) lParam)->Print(hwnd);
  return TRUE;
}

void Enum::Print(HWND hwnd)
{
cout << i << "   " << hwnd << endl;
i++;
}

void Enum::Run(void)
{
EnumWindows(&EnumWindowsProc, (int) this);
 
}


int main()
{
Enum en;
en.Run();
return 0;
}
« Последнее редактирование: 14-08-2005 20:46 от Finch » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Hooter
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #24 : 14-08-2005 20:19 » 

чувствую, что я даже ума не могу приложить, где может применяться статический метод класса (чтобы от этого применения польза была, а не ради примера).
Самый простой пример - счетчик экземляров класса.
class CountableClass
{
    CountableClass ()
    {
         incCounter();
    }

    virtual ~CountableClass ()
    {
         decCounter();
    }

    static void incCounter ()
    {
         // Критические секции и все такое...
         //  ...
         ++counter;
    }

    static void decCounter ()
    {
        // Критические секции и проч....
        --counter;
    }

    static int getCounter
    {
          // ... ...
          return counter;
    }

private:
    static int counter;
}
Записан
Alf
Гость
« Ответ #25 : 14-08-2005 21:12 » 

...
Не сочтите за наглость, но можно еще один прмерчик, но только такой в котором за основу использования статического метода берется не свойство вызова на прямую, а что-то другое.

По правде сказать, я не понял, что такое "свойство вызова на прямую", поэтому, возможно, мой пример будет не тем, что ты хотел увидеть. И все же...

Разбери внимательно стандартный паттерн GoF Singleton. Причем действительно разбери, а не прогляди код, т.е. вникни, для чего нужен этот паттерн, в каком контексте его следует применять, какие возможны альтернативные решения и чем они хуже (или лучше, если найдется и такая альтернатива). Если знаком с другими объектно-ориентированными языками, кроме С++, то прикинь, как этот паттерн можно реализовать их средствами.Там ты также встретишься с использованием статического метода.

Существует, конечно, множество других паттернов, также использующих статические методы. Однако Singleton - один из самых простых и доступных для понимания.
Записан
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #26 : 15-08-2005 12:50 » 

С примерами разбираюсь, большое спасибо. Альф, я никогда не имел дела с паттернами, и даже толком не знаю что это такое, с чем его едят и зачем, поэтому, извени уж, но слова типа
Цитата
Разбери внимательно стандартный паттерн GoF Singleton.
кроме ужаса у меня ничего не вызывают Жаль.

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

ещё один вопрос ...
Михалыч
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #27 : 15-08-2005 13:50 » 

Ну, я тоже близко еще не имел, но начинаю ковырять понемногу...
В поиск по сети Улыбаюсь Ссылок полно. Вот, например Улыбаюсь
http://citforum.ru/SE/project/pattern/
Записан

Поживем - увидим... Доживем - узнаем... Выживу - учту  Улыбаюсь
Alf
Гость
« Ответ #28 : 15-08-2005 13:55 » 

Альф, я никогда не имел дела с паттернами, и даже толком не знаю что это такое, с чем его едят и зачем, поэтому, извени уж, но слова типа
Цитата
Разбери внимательно стандартный паттерн GoF Singleton.
кроме ужаса у меня ничего не вызывают Жаль.

Я-то извиню, а вот твои будущие проекты - вряд ли извинят незнание паттернов. Так что если собираешься заниматься программированием профессионально, рано или поздно осваивать паттерны придется. Лучше рано, чем поздно, меньше велосипедов изобретешь.

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

С программированием та же ситуация. Выучив наизусть все грамматические конструкции, к примеру, С++, ты овладеешь лишь компьютерной грамотой. Кроме этого, нужно еще уметь составить сюжет и раскрыть его. А вот тут-то и необходимо владение алгоритмами, паттернами, объектным анализом и еще массой вещей, без которых серьезную программу не написать.

Книга "Банды четырех" в нашей библиотеке есть. Вроде бы есть и Ларман. И то, и другое есть в "Озоне". Так что преодолевай ужас и берись за дело.
Записан
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #29 : 15-08-2005 14:26 » 

Михалыч, спасибо за ссылку.
Цитата
Так что преодолевай ужас и берись за дело.
Да я не против, но время бы раздобыть. Почему в сутках не 48 часов?
Записан

ещё один вопрос ...
Страниц: [1] 2  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines