Как часто используется ключевое слово «volatile» в функции C ++ с точки зрения грамматики? - PullRequest
7 голосов
/ 04 октября 2011

Я задал эту функцию, основываясь на этой концепции (может быть, неправильной ?!): где бы ни существовал const, в этом месте может существовать летучее.

class classA
{
public:
    const int Foo() const;
}

Здесь первое «const» означает, что возвращаемое значение является const, мы не можем его изменить. второй const означает «Is Query», эта функция не может изменить переменную-член и не может вызвать неконстантную функцию.

Теперь доходит до volatile: я могу понять, что volatile делает с переменной, например, "volatile int a;" Однако я понятия не имею о разнице между следующим:

Case 1: The return type is volatile?
volatile void Function1();

Case 2: The function can only call volatile functions? Why add volatile here? Any example?
void Function2() volatile;

Case 3:   Is it valid? If yes, is it simply a combination of Case 1 and Case 2?
volatile void Function3() volatile;

Когда мы помещаем const в конце объявления функции, оно имеет красивое имя: "Is Query" Можете ли вы дать достойное имя / псевдоним «volatile» в случае 2? Я имею в виду, всякий раз, когда мы называем это имя, мы можем знать, что речь идет о случае 2, а не случае 1.

Заранее спасибо!

Ответы [ 3 ]

7 голосов
/ 04 октября 2011

Volatile имеет одну основную функцию: «ОСТАНОВИТЬ!» Этот объект связан с внешними ресурсами, и поэтому, когда я пишу в него, не переупорядочиваем запись относительно других энергозависимых операций чтения и записи, а также когдачитай, не переупорядочивай и не оптимизируй! ».

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

// just a silly example
struct HWOverlayClock {
  HWOverlayClock() { }

  int64_t getTime() volatile const { return timestamp; }

  int64_t timestamp;
};

// imagine we use an implementation defined way to put the
// object at some fixed machine address
volatile const HWOverlayClock clock __attribute__((at_address(0xbabe)));

Можно также поставить volatile на возвращаемое значение, но мне кажется, что это было бы менее полезно, поскольку возвращаемые значения обычно являются временными, а семантика volatile совершенно противоположнашкала временных.Помещение volatile в void особенно бессмысленно (const и volatile игнорируются, если помещаются на верхний уровень возвращаемого типа, если тип не является типом класса (то есть справа от *если это указатель), потому что эти возвращаемые значения не соответствуют памяти, вероятно, также сохраняются в регистрах реализациями).Помещение volatile на не верхний уровень для ссылок или указателей может быть полезным, как в следующем

struct Controller {
    HWOverlayClock volatile const* getClock() const { return clock; }

private:
    volatile const HWOverlayClock *clock;
};

Надеюсь, это поможет.

3 голосов
/ 04 октября 2011

второе значение const означает ", когда this является указателем на const" , эта функция не может изменить non- mutable memberпеременные из this и не могут вызывать неконстантные функции on this.

Там исправлено это для вас.

Теперь должно быть понятно, что означает функция-член volatile: ее можно вызывать, когда this является указателем на volatile.Требование, чтобы он мог вызывать другие функции-члены, только если они также являются изменчивыми, является следствием, но не основным смыслом.

3 голосов
/ 04 октября 2011

Второй констант означает «Запрос», эта функция не может изменить переменную-член и не может вызвать неконстантную функцию.

Да, это правильно.

volatile void Function1 ();
Тип возвращаемого значения volatile?

Возвращаемый тип функции здесь void (ничего не значит).Если он ничего не возвращает, нет смысла указывать, что возвращаемое ничто будет volatile.volatile предшествующая пустота будет избыточной.

Если тип возвращаемого значения был int, то да, volatile, предшествующий ему, применяется к типу возвращаемого значения.Это означает, что это возвращаемое значение может быть взято только в типе переменной, который volatile.

void Function2 () volatile;
Функция может вызывать только volatile функции?Зачем добавлять сюда летучие?Любой пример?

Да, это правильно.Смотрите пример кода ниже, который демонстрирует это.

volatile void Function3 () volatile;
Это действительно?Если да, это просто сочетание случая 1 и случая 2?

* В случае 1 volatile является избыточным. Если функция возвращает void (ничего), то не имеет смысла, что возвращаемое значение будет volatile, поэтому, по сути, выше, эквивалентнотолько случай 2.

пример Пример :

#include<iostream>

class Myclass
{
    public:
        volatile int i;
        Myclass():i(10){} 
        void doSomething()
        {
            std::cout<<"\nInside doSomething";
        }
        void doSomethingMore() volatile
        {
            std::cout<<"\nInside doSomethingMore";
            doSomething();   //Error


        }

};

int main()
{
     Myclass obj;
     obj.doSomethingMore();

     return 0;
}

"Is Query" Можете ли вы дать достойное имя / псевдонимв "изменчивый" в случае 2?Я имею в виду, что всякий раз, когда мы называем это имя, мы можем знать, что речь идет о случае 2, а не случае 1.

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

Это связано с тем, что все, что предшествует сигнатуре функции, относится к типу возвращаемого значения.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...