2012-04-20 11 views
10

Ho sentito che il fattore volatile è sovraccarico come const.sovraccarico volatile?

Se una funzione è sovraccaricata dal parametro volatile, quando viene richiamata la versione volatile?

Non riesco a immaginare una situazione in cui viene chiamata la versione volatile.  

+0

Aggiunto C++ tag; se questa non è la lingua di cui stai parlando, ti preghiamo di modificare la tua domanda per menzionare quel fatto piuttosto importante e ripeterla in modo appropriato. – Mat

+2

Questo è simile a 'const', Se si dispone di un oggetto qualificato' volatile', su di esso può essere chiamata solo la funzione 'volatile'. –

+1

oh, mi è sfuggito –

risposta

8

Il parametro volatile può essere applicato ai parametri, ma non è un fattore di sovraccarico se applicato direttamente al parametro. È tuttavia possibile utilizzarlo per distinguere i tipi di parametro. Per esempio, questo è legale:

void f(int &p) {}; //reference to int 
void f(volatile int &p) {}; //reference to volatile int 

Questo non è:

void f(int p) {}; 
void f(volatile int p) {}; 

La ragione è che nel primo esempio il riferimento non è ciò che è volatile, ma il numero intero. Nel secondo esempio, entrambi i tipi sono numeri interi e quindi dello stesso tipo.

Esistono anche metodi volatili. Sono simili a dichiarare che this è volatile. Poiché this è un puntatore e non sono in sé tipo contenente, il seguente è anche legale:

void c::f(int p) {}; 
void c::f(int p) volatile {}; 

È lo stesso come per sovraccarichi mediante const.

Questa parte rilevante dello standard C++ è §13.1 Dichiarazioni sovraccaricabili. Da C++ 11 draft n3290:

Le dichiarazioni dei parametri che differiscono solo per la presenza o l'assenza di const e/o volatile sono equivalenti. Cioè, gli specificatori di tipo const e volatile per ogni tipo di parametro vengono ignorati quando si determina quale funzione viene dichiarata, definita o chiamata. [Esempio:

typedef const int cInt; 
int f(int); 
int f(const int);   // redeclaration of f(int) 
int f(int) { /* ... */ } // definition of f(int) 
int f(cInt) { /* ... */ } // error: redefinition of f(int) 

- esempio fine]

Solo il const e tipo-specificatori volatili al livello più esterno della specifica tipo di parametro vengono ignorati in questo modo; Gli identificatori di tipo const e volatile sepolti all'interno di una specifica del tipo di parametro sono significativi e possono essere utilizzati per distinguere le dichiarazioni di funzioni sovraccariche . In particolare, per qualsiasi tipo T,, pointer to const T e pointer to volatile T sono considerati tipi di parametri distinti, come lo sono reference to T, reference to const T e reference to volatile T.

124) Quando un tipo di parametro comprende un tipo di funzione, come ad esempio nel caso di un tipo di parametro che è un puntatore alla funzione, il const e tipo-specificatori volatili al livello più esterno delle specifiche tipo parametro anche il tipo di funzione interna è ignorato.

+0

Questa è una buona risposta – Pete

10

Ecco un esempio:

#include <iostream> 

struct A { 
    void foo() { 
     std::cout << "in non-volatile" << std::endl; 
    } 
    void foo() volatile { 
     std::cout << "in volatile" << std::endl; 
    } 
}; 

int main() 
{ 
    A a; 
    a.foo(); 
    volatile A b; 
    b.foo(); 
} 

b.foo() chiamerà il volatile sovraccarico. Se struct A non ha avuto un sovraccarico volatile per foo, b.foo() non sarebbe valido.

+0

Non così veloce. Questa domanda sembra riguardare parametri volatili e questi non sono un fattore di sovraccarico. –

+0

Questo non era (non è) completamente chiaro per me - e Pete ha già postato una risposta sui parametri di funzione. – Mat

+0

Sto bene, ma anche @Pete non sta dando la risposta completa. Forse dovremmo consolidarci. –

3

Scrivere un programma di prova per scoprirlo.

void func(const int& a) 
{ 
    std::cout << "func(const)" << std::endl; 
} 

void func(const volatile int& a) 
{ 
    std::cout << "func(const volatile)" << std::endl; 
} 

int main() 
{ 
    const int a = 0; 
    const volatile int b = 0; 
    func(a); 
    func(b); 
    system("pause"); 
    return 0; 
} 

uscita volontà:

func(const) 
func(const volatile)