为模拟的std :: fstream类避免"优势继承"警告

M. *_*ley 8 c++ fstream mocking compiler-warnings visual-c++

我正在使用googlemockstd::fstream在我的单元测试中模拟出一个对象,如下所示:

TEST_F(SomeTest, SomethingIsDoneCorrectly)
{
    class MockFstream : public std::fstream {};
    MockFstream lMockFstream;
    // Expectations and assertions here
}
Run Code Online (Sandbox Code Playgroud)

当我编译时,我得到以下警告:

警告1警告C4250:'SomeTest_SomethingIsDoneCorrectly_Test :: TestBody :: MockFstream':通过优势继承'std :: basic_istream <_Elem,_Traits> :: std :: basic_istream <_Elem,_Traits> :: _ Add_vtordisp1'

警告2警告C4250:'SomeTest_SomethingIsDoneCorrectly_Test :: TestBody :: MockFstream':通过优势继承'std :: basic_ostream <_Elem,_Traits> :: std :: basic_ostream <_Elem,_Traits> :: _ Add_vtordisp2'

我更喜欢干净的构建输出,所以我想要抑制这些特定的警告,但我正在编写跨平台代码,所以我也更愿意避免使用特定于编译器的#pragmas.

我可以在googlemock对象中做些什么来隐藏这些警告吗?

M. *_*ley 8

事实证明,这些警告是Microsoft C++ STL中一些怪癖的副作用.我引用了下面相关Microsoft Connect问题的解释.

我的解决方案只是在我的mock中实现继承函数的空版本:

TEST_F(SomeTest, SomethingIsDoneCorrectly)
{
    class MockFstream : public std::fstream
    {
        void _Add_vtordisp1() { } // Required to avoid VC++ warning C4250
        void _Add_vtordisp2() { } // Required to avoid VC++ warning C4250
    };
    MockFstream lMockFstream;
    // Expectations and assertions here
}
Run Code Online (Sandbox Code Playgroud)

一个从微软解释一下,为什么会出现警告:

这里的故事有点复杂.VC有一个模糊的编译器选项/ vd2(在http://msdn.microsoft.com/en-us/library/7sf3txa8.aspx上有记录),修复了一个涉及虚拟基类的模糊错误.默认情况下,VC执行的操作与C++标准略有不符./ vd2将VC的行为更改为符合,但这本身会影响类布局.(这种布局差异是为什么默认值没有改变为符合 - 这会破坏用户尝试混合使用VC的不同主要版本编译的代码.我们的C++标准库实现禁止这种混合,但编译器本身有点更宽松.)因此,如果用户想要/ vd2,他们必须以这种方式编译所有内容.

扭曲是布局错误(/ vd2修复)影响iostreams,它使用虚拟基类,我们的iostreams实现有一个单独编译的组件(在msvcp100.dll/libcpmt.lib/etc.中).当MS构建STL的DLL/LIB时,它们是以默认方式编译的,没有/ vd2.因此,使用/ vd2的人无法使用iostream,或者他们会遇到奇怪的崩溃.呸.

因此,我们添加了do-nothing虚函数_Add_vtordisp1()和_Add_vtordisp2().它们的存在使得VC完全符合布局,无论是否使用/ vd2,因此使得iostream可以双向使用.

_Add_vtordisp1()和_Add_vtordisp2()触发警告C4250,谈论支配地位.这个警告实际上是完全无用的 - 它说编译器将完全按照标准要求它执行.因此,我们在STL的头文件中对它进行抑制(必须是/ W4/analyze clean).如果您是从fstream派生的,则需要在自己的代码中禁止显示此警告.