簡體   English   中英

使用臨時實例的const正確性

[英]Const correctness with temporary instances

以下是具有常見錯誤的“范圍鎖定”習慣用法的示例:未創建局部變量,因此鎖定無效。 這段代碼在VC ++ 2010和Comeau C ++在線編譯完美無瑕:

class Mutex
{
public:
    void lock() {}
};

class ScopedLock
{
public:
    ScopedLock() : m_pm(0) {}
    ScopedLock(Mutex& m) : m_pm(&m) { m_pm->lock(); }

private:
    Mutex* m_pm;

private:
    ScopedLock& operator =(const ScopedLock&);
    ScopedLock(const ScopedLock&);
};

class X
{
public:
    void foo() const
    {
        ScopedLock(m_mutex);
    }

private:
    Mutex m_mutex;
};


int main()
{
    X x1;
    x1.foo();
}

如果注釋掉ScopedLock的默認構造函數,則兩個編譯器都會給出錯誤:

錯誤C2512:'ScopedLock':沒有合適的默認構造函數可用

(當ScopedLock正確使用時,即創建局部變量: ScopedLock guard(m_mutex);然后編譯按預期失敗。將m_mutex聲明為可變修復問題。)

我有兩個問題:

  1. 為什么X::foo編譯? 似乎編譯器能夠以某種方式將const Mutex& Mutex&Mutex&

  2. 扮演ScopedLock默認構造函數的角色是什么,所以編譯成功了?

謝謝。

更新:我找到了答案。 看來是ScopedLock(m_mutex); statement創建一個m_mutex類型的局部變量ScopedLock 不是暫時的。 這就是為什么ScopedLock::ScopedLock默認構造函數是必需的。

你自己回答了這個問題。

看來是ScopedLock(m_mutex); statement創建一個ScopedLock類型的局部變量m_mutex

解釋可在標准的6.8節歧義解決方案中找到:

在涉及表達式語句和聲明的語法中存在歧義:具有函數式顯式類型轉換[5.2.3]的表達式語句,因為其最左側的子表達式與第一個聲明符以(a)開頭的聲明無法區分。 在這些情況下,該聲明是一個聲明

標准然后列出T(a); 作為一個真正聲明的聲明的例子。 它相當於T a;

這是臭名昭着的C ++“最令人煩惱的解析”的一種變體。

我很確定你的問題是第26行: ScopedLock(m_mutex);

相反,它應該類似於ScopedLock a_variable_name(m_mutex);

當我做出改變時,我得到了預期的錯誤:

constCorrectness.cpp: In member function ‘void X::foo() const’:
constCorrectness.cpp:26: error: no matching function for call to ‘ScopedLock::ScopedLock(const Mutex&)’
constCorrectness.cpp:18: note: candidates are: ScopedLock::ScopedLock(const ScopedLock&)
constCorrectness.cpp:11: note:                 ScopedLock::ScopedLock(Mutex&)
constCorrectness.cpp:10: note:                 ScopedLock::ScopedLock()

也許有人可以為我們解釋 ScopedLock(m_mutex) 它是否聲明了某個功能? 而不是像提問者那樣調用構造函數? 更新:解決這個問題。 我認為這只是一個變量聲明(即括號被忽略。)

問題是X :: foo()方法被聲明為const - 這意味着它不會改變(改變)對象。

ScopedLock()構造函數沒有接受對Mutex對象的不可變(const)引用的重載。

修復此問題需要將m_mutex聲明為可變,或者提供適當的重載ScopedLock()構造函數。 我認為前者更可取。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM