Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> почему трубуется static? 
:(
    Опции темы
mrgloom
Дата 18.2.2013, 17:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 8.6.2011

Репутация: нет
Всего: нет



Код

class CMyDlg : public CDialog
{

    class CMyTask : public CThreadClass::CTaskClass
    {
    public:
        int         var;

        CMyTask() :
        var(0)
        {}

        virtual void Execute()
        {

            double val = CMyDlg::Calc(var); //требует чтобы Calc было static illegal call of non-static member function

        }
    };
    
    //....
    
private:
    double Calc(var);
public:
    int m_some_const;
}


требует чтобы Calc было static, но Calc внутри зависит от m_some_const и соответсвенно её тоже надо делать тогда статик, но тогда 
Цитата

unresolved external symbol "public: static int CMyDlg::m_some_const

как разрешить проблему и как правильно?

Это сообщение отредактировал(а) mrgloom - 18.2.2013, 17:24
PM MAIL   Вверх
Alexeis
Дата 18.2.2013, 18:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 12
Всего: 459



  Он требует статик потому что в функцию Execute не передан указатель на CMyDlg .  С ним можно было написать MyDlg->Calc(var); не делая Calc статической


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Albor
Дата 18.2.2013, 18:06 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 589
Регистрация: 28.2.2009

Репутация: нет
Всего: 9



Вы вызываете не статическую функцию класса не создав объект, поэтому компилятор и ругается. Соответственно, после того как функция объявлена как статическая, она не может использовать не статические поля.
PM MAIL ICQ   Вверх
korian
Дата 18.2.2013, 18:54 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 3
Всего: 17



Цитата(mrgloom @  18.2.2013,  16:19 Найти цитируемый пост)
double val = CMyDlg::Calc(var);

похоже на попытку писать как на java. В c++, внутренний класс не содержит в себе автоматом ссылку на внешний класс. Т.е. в c++ они все static как бы. При этом к приватным  полям доступа тоже кажись не дадут. (Не помню).
Можно починить так как ниже, но это наверно не лучший вариант.

Код

class CMyDlg : public CDialog
{
    class CMyTask : public CThreadClass::CTaskClass
    {
    public:
        CMyDlg &m_dlg;
        int         var;
        CMyTask(CMyDlg &dlg) :
        m_dlg(dlg)
        var(0)
        {}
        virtual void Execute()
        {
            double val = m_dlg.Calc(var); //требует чтобы Calc было static illegal call of non-static member function
        }
    };
    
    //....
    
private:
    friend class CMyTask;
    double Calc(var);
public:
    int m_some_const;
}


Добавлено через 1 минуту и 52 секунды
Цитата(mrgloom @  18.2.2013,  16:19 Найти цитируемый пост)
unresolved external symbol "public: static int CMyDlg::m_some_const

не константные static переменные должны быть определены в cpp-файле (в добавок к определению в h-файле).

static int CMyDlg::m_some_const = 0;

PM   Вверх
mrgloom
Дата 19.2.2013, 10:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 8.6.2011

Репутация: нет
Всего: нет



Цитата

Вы вызываете не статическую функцию класса не создав объект, поэтому компилятор и ругается. Соответственно, после того как функция объявлена как статическая, она не может использовать не статические поля. 


Цитата

не константные static переменные должны быть определены в cpp-файле (в добавок к определению в h-файле).

static int CMyDlg::m_some_const = 0;



эти ответы помогли, только надо 
Код

int CMyDlg::m_some_const = 0;


А почему плохое решение?
Код

CMyDlg &m_dlg;  //непонятно разве так можно объявлять переменную?
        int         var;
        CMyTask(CMyDlg &dlg) :
        m_dlg(dlg)

PM MAIL   Вверх
korian
Дата 19.2.2013, 17:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 3
Всего: 17



Цитата(mrgloom @  19.2.2013,  09:13 Найти цитируемый пост)
А почему плохое решение?

Если надо писать "friend class ...", то я автоматом считаю решение не хорошим. Но я ничего не могу сказать по поводу того, почему оно плохое. Т.е. надо знать пороблему и понять, можно ли сделать по другому (обычно можно).


Цитата(mrgloom @  19.2.2013,  09:13 Найти цитируемый пост)
//непонятно разве так можно объявлять переменную?

да, я запятую пропустил, после m_dlg(dlg)
PM   Вверх
Alexeis
Дата 20.2.2013, 09:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 12
Всего: 459



Цитата(korian @  19.2.2013,  18:04 Найти цитируемый пост)
Если надо писать "friend class ...", то я автоматом считаю решение не хорошим.
 Ну да, наверное, дураки придумали это ключевое слово для дураков. Наверное, и слово декомпозиция для вас ругательное. Вот как раз, когда разбивают задачу на подзадачи с применением ООП возникает необходимость формировать сильные связи внутри группы объектов, которые по логике являются сильно связанными. Именно для этого и существует friend для обозначения группы сильно связанных объектов, которые решают подзадачи одной более сложной задачи. Если же friend используется для написания кода слабо связанных объектов, то это действительно нехорошее решение. 
  Грубо говоря, если А предназначено для B, то А является другом для B, что и реализует модификатор friend. 


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
mrgloom
Дата 20.2.2013, 10:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 8.6.2011

Репутация: нет
Всего: нет



ну я в итог сделал const функцию и переменную. вроде бы это особых ограничений не накладывает.


я говорил про строчку
Код

CMyDlg &m_dlg;


т.е. когда так в функцию передается понятно аля  func(CMyDlg &m_dlg), а что значит когда так объявляется переменная?
PM MAIL   Вверх
Alexeis
Дата 20.2.2013, 12:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 12
Всего: 459



  Это значит, что функция ожидает в качестве параметра ссылку на переменную. Ссылка это некоторое подобие указателя с той лишь разницей, что ссылка всегда указывает на реально существующую переменную. Ссылка это некоторый псевдоним переменной, поэтому при обращении к полям или функциям объекта синтаксис как у переменной. Ссылка инициализируется в момент создания и дальше не уже не может менять свою привязку к переменной. К примеру, переменная это ни что иное как адрес некоторой области памяти. Вот если 2е переменные определяют одну и ту же область памяти, то одна из переменных является ссылкой. Не путать с указателем. Указатель хранит адрес на этапе исполнения, а переменная (ссылка) хранит данные по некоторому адресу в памяти. 

Это сообщение отредактировал(а) Alexeis - 20.2.2013, 12:29


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
korian
Дата 20.2.2013, 14:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 3
Всего: 17



Цитата(Alexeis @  20.2.2013,  08:22 Найти цитируемый пост)
Если же friend используется для написания кода слабо связанных объектов, то это действительно нехорошее решение. 

По моему опыту, в 99.99% так оно и есть. Т.е. если friend используется в коммерческом проекте (не библиотека, или шо-то другое, что должно быть сверх унифицировано), то он используется именно там, где он нафиг не нужен.
Цитата(Alexeis @  20.2.2013,  08:22 Найти цитируемый пост)
Ну да, наверное, дураки придумали это ключевое слово для дураков.

Слово придумали для того, чтобы можно было сделать все, что может только потребоваться.
Я например не собираюсь использовать слово volatile в одно-поточном приложении. Но в c++ оно есть.
При чем я его не буду использовать даже там, где теоретически я могу сделать доступ из несколько потоков (продумать на будущее, написать более унифицировано, так сказать), потому что у меня все равно приложение будет одно-поточное.

оператор delete, кстати, туда же к friend. Т.е. я считаю, что в реальном проекте использовать его нельзя.
Использовать его есть смысл только в небольших участках кода, которые требуют оптимизации, что по моему опыту не более 0.01% случаев и реальный коммерческий проект в них никогда не попадает.

Это сообщение отредактировал(а) korian - 20.2.2013, 17:22
PM   Вверх
Alexeis
Дата 20.2.2013, 17:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 12
Всего: 459



Цитата(korian @  20.2.2013,  15:12 Найти цитируемый пост)
По моему опыту, в 99.99% так оно и есть. Т.е. если friend используется в коммерческом проекте (не библиотека, или шо-то другое, что должно быть сверх унифицировано), то он используется именно там, где он нафиг не нужен.

По-моему опыту, браться на С++ писать что-то сверх унифицированное уже ошибка. Язык максимально ориентирован на статическое связывание решение системных высокопроизводительных задач. Все вкусняжки языка в шаблонах/ссылках/инлайнах/константах/типах времени компиляции. Короче, то что генерится на этапе компиляции. В STL/Boost виртуальных методов не встретишь. Как раз эти самые сильные связи наилучшее, что можно творить на С++ . 
Цитата(korian @  20.2.2013,  15:12 Найти цитируемый пост)
Я например не собираюсь использовать слово volatile в одно-поточном приложении. Но в c++ оно есть.

  Ну если данные меняются в прерывании, то без него никуда. Что такое С++ ? Высокопроизводительные движки типа сервера бд (например firebird), драйвера и системные утилиты, движки 3D игр, веб сервера, математические движки типа Матлаб, среды симуляции LabView, прошивки контроллеров (ПЛК), элементы ОС. Как тут жить без volatile и friend потоков и прерываний?  

Про оператор delete вообще smile . 

P.S. Чувствую, ща придется тему разделять и флуд отсюда отрезать.




--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
korian
Дата 20.2.2013, 17:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 3
Всего: 17



Цитата(Alexeis @  20.2.2013,  16:28 Найти цитируемый пост)
По-моему опыту, браться на С++ писать что-то сверх унифицированное уже ошибка. 

как бы тот же boost я считаю уже чем-то сверх унифицированным, писать его - ошибка?
и, в принципе, не понял, как весь первый абзац относится к friend?
дайте реальный пример, где вы считаете, что friend необходим, я покажу вам, как от него избавиться. Причем в результате код получиться более читабельным.

Цитата(Alexeis @  20.2.2013,  16:28 Найти цитируемый пост)
ро оператор delete вообще 

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

Цитата(Alexeis @  20.2.2013,  16:28 Найти цитируемый пост)
Как тут жить без volatile и friend потоков и прерываний?  

где я написал, что эти слова в языке не нужны совсем? я такого не писал.
PM   Вверх
Alexeis
Дата 20.2.2013, 18:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 12
Всего: 459



Цитата(korian @  20.2.2013,  18:38 Найти цитируемый пост)
дайте реальный пример, где вы считаете, что он нужен, я покажу как от него избавиться.

  Реальный пример будет не на одну сотню строк, так что вот псевдокод.

Код

template<typename T>
class SubTaskA<T>
{
T &Parent; 
public:
        SubTaskA(T &aParent)Parent(aParent){}
    bool ExecuteSubtask(...)
    {
        ReadFromDevice(val);
                pr_val = ProcessVal(val);
        WriteToDevice(pr_val);
                Parent.UpdateInternalParentState(pr_val);
    }
};

class TaskA
{
friend SubTaskA<TaskA>;
protected:
    SubTaskA<TaskA> Task1;
    void UpdateInternalParentState(...);
public:
    TaskA( void ) : Task1(*this){};    
    void DoTask()
    {
        Task1.ExecuteSubtask(...);
        Task2.ExecuteSubtask(...);
    }

};


Цитата(korian @  20.2.2013,  18:38 Найти цитируемый пост)
где я написал, что эти слова в языке не нужны совсем? я такого не писал. 

   Так я и не опровергал утверждение, о том что они совсем не нужны. Я опровергал, то что они редко используются в реальных проектах на С++ . Специфика языка такова, что эти модификаторы не просто дополнительные придатки, а основной рабочий механизм. 


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
korian
Дата 20.2.2013, 18:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 3
Всего: 17



учитывая, что это псевдокод, то у для меня тут или в классе TaskA, функция UpdateInternalParentState должна быть public.
Или второй вариант (тоже псевдокод):
Код

template<typename T>
class SubTaskA<T>
{
typedef ... UpdateFunction;
UpdateFunction listener;
public:
        SubTaskA(UpdateFunction aParent)listener(aParent){}
    bool ExecuteSubtask(...)
    {
        ReadFromDevice(val);
                pr_val = ProcessVal(val);
        WriteToDevice(pr_val);
                listener(pr_val);
    }
};
class TaskA
{
protected:
    SubTaskA<TaskA> Task1;
    void UpdateInternalParentState(...);
public:
    TaskA( void ) : Task1(&UpdateInternalParentState){};    
    void DoTask()
    {
        Task1.ExecuteSubtask(...);
        Task2.ExecuteSubtask(...);
    }
};


Не нравится передача указателя на функцию или функций больше чем одна - можно использовать интерфейс (в смысле полиморфизм).


Это сообщение отредактировал(а) korian - 20.2.2013, 18:44
PM   Вверх
NoviceF
Дата 20.2.2013, 21:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 313
Регистрация: 13.3.2012
Где: Ростов-на-Дону

Репутация: нет
Всего: 2



Цитата(korian @  20.2.2013,  15:12 Найти цитируемый пост)
оператор delete ... в реальном проекте использовать его нельзя.


А можно тут небольшое пояснение? Как удалять объекты выделенные new?
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1041 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.