【问题标题】:Google Mock: Mocked overloaded functions create warning C4373Google Mock:模拟的重载函数会产生警告 C4373
【发布时间】:2011-01-09 11:33:28
【问题描述】:

我正在使用 Google Mock 和 VS2010 模拟一个具有 2 个重载函数的 C++ 类:

#include "stdafx.h"
#include "gmock/gmock.h"

#include "A.h"

class MockA : public A
{
public:
    // ...
    MOCK_METHOD3(myFunc, void(const int id, const int errorCode, const CString errorMsg));
    MOCK_METHOD1(myFunc, void(const CString errorMsg));
    // ...
};

每次编译时都会收到以下警告两次:

1>c:\dev\my_project\tests\mocka.h(83): warning C4373: 'MockA::myFunc': virtual function overrides 'A::myFunc', previous versions of the compiler did not override when parameters only differed by const/volatile qualifiers
1>          c:\dev\my_project\my_project\include\a.h(107) : see declaration of 'A::myFunc'

知道为什么吗?
这是正确的行为吗?
我怎样才能避免这种情况?

【问题讨论】:

  • 确保您使用的是正确的变体——当您覆盖 A 的方法是 const 时,应使用 MOCK_CONST_METHOD。
  • @Billy ONeal - 方法本身不是 const,只有它的参数是。我还应该使用 MOCK_CONST_METHOD 吗?
  • 否;在这种情况下,你应该做你正在做的事情:)

标签: c++ visual-c++ mocking overloading googlemock


【解决方案1】:

如果这是新代码,你应该没问题。 C4373 warning 表示旧版本的 Visual Studio 违反了标准。来自链接的文档:

之前的编译器版本 Visual C++ 2008 将函数绑定到 基类中的方法,然后 发出警告信息。随后的 编译器的版本忽略 const 或 volatile 限定符,绑定 派生方法中的函数 类,然后发出警告 C4373。这 后一种行为符合 C++ 标准。

只有当您破坏了依赖于 Visual Studio 不正确行为的代码时,这才会成为问题。

【讨论】:

  • 我当然希望你是对的。你有参考来支持这个吗?人们在某个地方讨论这确实是过去的错误行为?另外 - 我怎样才能忽略这个特定的警告?
  • @Jon,在链接中有解释。请注意最后一部分,“后一种行为符合 C++ 标准。”
  • 谢谢。我使用以下内容来抑制警告:stackoverflow.com/questions/2541984/…
  • 我不明白,所有const 都在正确的位置。无论如何,警告已经被触发了,为什么只针对某些方法的子集?
【解决方案2】:

对我来说(在 VS 2010 中),在原始类型参数(我看到你也有)上指定 const 会导致这种行为。每当我想覆盖的基类函数中存在这种情况时,我无法以某种方式指定模拟,以免出现此警告;当只有类类型 const 值 / const 引用参数时,警告永远不会发生。

所以在我看来,这种情况下的警告实际上是编译器中的一个错误(因为签名完全相同)。

【讨论】:

    【解决方案3】:

    建议的替代方法:

    #include "stdafx.h"
    #include "gmock/gmock.h"
    
    #include "A.h"
    
    class MockA : public A
    {
    public:
        // ...
    
        void myFunc(const int id, const int errorCode, const CString errorMsg) {
          mocked_myFunc3(id, errorCode, errorMsg);
        }
    
        void myFunc(const CString errorMsg) {
          mocked_myFunc1(errorMsg);
        }
    
        MOCK_METHOD3(mocked_myFunc_3, void(const int id, const int errorCode, const CString errorMsg));
        MOCK_METHOD1(mocked_myFunc_1, void(const CString errorMsg));
        // ...
    };
    

    【讨论】:

      【解决方案4】:

      我意识到这是一个老问题,但由于我现在自己偶然发现了这个问题,所以我想分享我的解决方案(或至少是解释):

      问题可能是您的 声明 有一个 const 参数,编译器会忽略该参数。正是 定义 可以有效地使用 const 作为参数。

      现在google mock faq 中也提到了,为了消除警告,请从函数声明的参数中删除const

      在我的情况下,我发现它仍然很难,因为函数实现是针对头内的模板类,其中声明和定义都发生在一起完成。解决方案可能是在包含模拟类的标题时禁用警告。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-10-16
        • 2021-09-08
        • 2017-08-12
        • 1970-01-01
        • 2011-06-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多