【问题标题】:volatile overloading?易失性重载?
【发布时间】:2012-04-20 08:14:51
【问题描述】:

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

如果函数被 volatile 参数重载, volatile-version 什么时候调用?

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

【问题讨论】:

  • 添加了 C++ 标签;如果这不是您所说的语言,请编辑您的问题以提及这一相当重要的事实并适当地重新标记。
  • 这和const类似,如果你有一个volatile限定的对象,那么只能调用volatile函数。
  • 一般来说,几乎所有适用于const 限定符的东西也适用于volatile 限定符。该标准大多将它们统称为cv-qualifiers
  • Herevolatile 成员函数的一个有趣使用(或滥用),用于在编译时检查对象是否以线程安全的方式被访问。基本上,您通过volatile 引用访问未锁定对象,通过普通引用访问锁定对象,并且每个操作都有一个volatile 重载,它首先获取锁。

标签: c++ overloading volatile


【解决方案1】:

这是一个例子:

#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 没有foo 的易失性重载,b.foo() 将无效。

【讨论】:

  • 没那么快。这个问题似乎是关于 volatile 参数的,这些不是重载的因素。
  • 这对我来说并不完全清楚——Pete 已经发布了关于函数参数的答案。
  • 我很好,但@Pete 也没有给出完整的答案。也许我们应该合并。
  • 为此,我将您的优点纳入接受的答案并为您投票。
  • 我在你的标准中引用了一个引用,希望你不介意:)
【解决方案2】:

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

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

还有 volatile 方法。它们类似于将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 类型说明符是 也被忽略了。

【讨论】:

    【解决方案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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-21
      • 2013-11-13
      • 1970-01-01
      • 1970-01-01
      • 2018-01-18
      • 2018-08-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多