11

我听说 volatile 是像 const 一样的重载因素。

如果一个函数被 volatile 参数重载,那么什么时候调用 volatile 版本?

我无法想象调用 volatile-version 的情况。 

4

3 回答 3

10

这是一个例子:

#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()将调用volatile重载。如果struct A, 没有 volatile 重载foob.foo()则无效。

于 2012-04-20T08:20:01.380 回答
8

volatile 可以应用于参数,但直接应用于参数时,它不是重载的因素。然而,可以使用它来区分参数的类型。例如,这是合法的:

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

这不是:

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

原因是在第一个示例中,引用不是易失性的,而是整数。在第二个示例中,两种类型都是整数,因此是相同的类型。

还有一些不稳定的方法。它们类似于宣布this易变。因为this是指针而不是包含类型本身,所以以下也是合法的:

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

这与通过 重载相同const

C++ 标准的这个相关部分是 §13.1 可重载声明。来自 C++11 草案 n3290:

仅在存在或不存在 const 和/或 volatile 方面不同的参数声明是等效的。也就是说,在确定声明、定义或调用哪个函数时,将忽略每个参数类型的 const 和 volatile 类型说明符。[ 例子:

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)

—结束示例]

只有参数类型说明最外层的 const 和 volatile 类型说明符以这种方式被忽略;隐藏在参数类型规范中的 const 和 volatile 类型说明符很重要,并且可用于区分重载函数声明124。特别是,对于任何类型 T,pointer to Tpointer to const Tpointer to volatile T被视为不同的参数类型,如reference to Treference to const Treference to volatile T

124) 当参数类型包括函数类型时,例如在参数类型是指向函数的指针的情况下,内部函数类型的参数类型规范的最外层的 const 和 volatile 类型说明符也是忽略。

于 2012-04-20T08:21:07.323 回答
3

编写一个测试程序来找出答案。

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;
}

将输出:

func(const)
func(const volatile)
于 2012-04-20T08:22:10.997 回答