2010-04-13 144 views
3
#include <iostream> 
#include <assert.h> 

using namespace std; 

struct Base 
{ 
    Base() : m_member1(1) {} 

    Base(const Base & other) 
    { 
    assert(this != &other); // this should trigger 
    m_member1 = other.m_member1; 
    } 

    int m_member1; 
}; 

struct Derived 
{ 
    Derived(Base & base) : m_base(m_base) {} // m_base(base) 

    Base & m_base; 
}; 

void main() 
{ 
    Base base; 

    Derived derived(base); 

    cout << derived.m_base.m_member1 << endl; // crashes here 
} 

上述示例是錯誤構造函數的綜合版本。 我在類成員Derived::m_base上使用了引用,因爲我想確保成員將在構造函數調用時被初始化。 一個問題是GCC和MSVC都沒有在m_base(m_base)處給我一個警告。但對我來說更嚴重的是assert發現一切正常,應用程序在後來崩潰(有時遠離錯誤)。問:有什麼方法可以表明這樣的錯誤嗎?爲什麼`A&a = a`有效?

回答

3

斷言不會觸發,因爲您沒有在調用m_base(m_base)中創建Base的實例。這只是初始化參考Base& m_base。如果您確實想調用複製構造函數,則將m_base聲明爲值Base m_base

此外,捕捉這種錯誤的一種方法是讓您的編譯器警告未使用的參數。 gcc標誌是-Wunused-parameter-Wextra -Wunused

+0

通常A&a = a;給我提到的編譯器警告。但在這個例子中,這個警告沒有出現。沒有調用複製構造函數的答案是正確的。但我的問題是懸而未決的參考。 – psaghelyi 2010-04-13 21:20:37

+0

@psag,因爲你沒有使用參數'Base&base',所以在這種情況下我會提出警告。但是你是對的,我似乎無法讓gcc直接警告'm_base(m_base)'(不管它是否是引用)。 – 2010-04-13 21:34:51

+0

這是一個討論自我初始化的錯誤報告('int i = i'):http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34772。但是當你使用這個變量的時候,它似乎把注意力集中在警告上,而不是當你用它自己初始化的時候,這似乎是它應該警告你的地方。 – 2010-04-13 21:36:10

相關問題