2010-04-13 143 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

相关问题