编译器错过了无效的构造函数调用,并调用了非existant(或私有)默认构造函数

时间:2017-06-22 15:31:33

标签: c++ c++11

我有一个继承自其他几个基类的类的构造函数:

Derived::Derived() :    MyRpc< Derived, DERIVED_RPC_CLASS_ID, true  > ( Derived::sServerName ),
                    MyEventSource<Derived>( *this ),
                    Smasher<Derived>( *this )

{ 
}

正在调用Smasher的默认构造函数。同样奇怪的是,如果我将Smash私有的默认构造函数或者我直接删除它,编译器仍然会生成一个公共默认构造函数并调用它。

以下是我对smasher的定义:

class SmasherBase
{
    SmasherBase()=delete;
    SmasherBase( const char *name)
    {}
    .
    .
};

template< typename ... >  class Smasher : public SmasherBase
{
    Smasher()=delete;
};

template< typename LocalServerRPC_T >
class Smasher<LocalServerRPC_T> : public SmasherBase
{
public:
    Smasher()=delete;
    Smasher( LocalServerRPC_T &localServer, const char *name ) : SmasherBase( name ),
                                                                    mLocalServer( localServer )
    {
        ....
    }

    ~Smasher()
    {
    }

    typedef Smasher<LocalServerRPC_T>   Smasher_t;

protected:
    LocalServerRPC_T    &mLocalServer;
};

我希望编译器抱怨我没有调用现有的构造函数,如:

error: no matching function for call to 'Smasher<Derived>::Smasher(EksoCAT&)' 

但它很乐意编译上面的代码,然后创建一个默认构造函数,超出我的反对意见。它还创建并调用基类的默认构造函数。

我甚至尝试将默认构造函数设为私有,希望它至少会意识到它不应该在其位置创建编译器生成的默认构造函数,并且可能会抱怨构造函数是私有的。

没有这样的运气。代码很愉快地生成,当我运行时,我可以进入幻像默认构造函数。

我正在使用GNU 4.8.3 C ++编译器。我还清理,重建,搜索这些文件的旧版本,以确保它们没有被使用等等无济于事。

感谢大家的任何帮助和想法。

1 个答案:

答案 0 :(得分:1)

我的通灵调试技巧告诉我,你的班级Derived继承自Smasher<Derived>。在这种情况下,您对Smasher<Derived>(*this)的调用实际上是调用Smasher复制构造函数,您自己尚未删除或定义,因此编译器很乐意为你生成一个。调试器几乎肯定不会向您显示被调用的确切构造函数。