【问题标题】:Change class template member visibility更改类模板成员可见性
【发布时间】:2012-09-11 14:13:57
【问题描述】:

假设我有一个 C++ 类模板:

template <class _T>
class MyClass
{
public:
    int func();

private:
    _T internal;
};

我想要一种为此模板指定一个布尔值的方法,如果该值为真,则会将此模板中的每个成员设为公开。

例如:

MyClass<SomeClass, false> c1;
c1.internal.someFunc(); // ERROR

MyClass<SomeOtherClass, true> c2;
c2.internal.someFunc(); // SUCCESS

对于那些想知道的人,我正在使用 gtest 和 gmock 来模拟具体的类。所以,在我的一个单元测试中,我会有类似的东西:

TEST(MyClass, Test1) {
    MyClass<SomeMockClass, true> c1;
    EXPECT_CALL(c1.internal, someFunc()).Times(1);
}

对于这个测试模板,我的代码必须可以访问 internal。在生产中,我想对用户隐藏它。

我使用的是 msvc 11 (Visual Studio 2012),因此我可以访问一些 C++11 功能和元编程结构。

【问题讨论】:

  • _T 绝对不是一个好名字。它是为实现而保留的,尤其是这个,因为我知道它被用作宏来根据您的程序是否使用宽字符来加宽字符串。
  • 好提示@chris。我以这个为例,而且我的模板几乎更具体,但很高兴知道这一点。

标签: c++ templates


【解决方案1】:

你可以从主类继承一个测试助手,你声明朋友的助手,然后公开你感兴趣的元素:

#include <iostream>

template<typename T> class TestMyClass;

template<typename T>
class MyClass
{
    friend class TestMyClass<T>;
    public:
        int func();
    private:
        T internal;
};

template <class T>
class TestMyClass : public MyClass<T>
{
    public:
        using MyClass<T>::internal;
};

int main()
{
    TestMyClass<double> s;
    s.internal = 5;
    std::cout << s.internal << "\n";
    return 0;
}

【讨论】:

  • 这是我采用的解决方案的一个非常接近的答案。我刚刚开始使用 GoogleTest 并遇到了私人成员的问题。我没有意识到他们已经提供了解决方案:code.google.com/p/googletest/wiki/…
【解决方案2】:

您可以通过类模板专业化来做到这一点,但是,这确实意味着您在进行更改时需要同时修改两组代码:

#include <iostream>

template <class T, bool visible>
class MyClass
{
};

template <class T>
class MyClass<T, true>
{
public:
    int func();
    T internal;
};

template <class T>
class MyClass<T, false>
{
public:
    int func();
private:
    T internal;
};

int main()
{
    MyClass<int, true> s;
    s.internal = 5;
    std::cout << s.internal << "\n";
    return 0;
}

【讨论】:

  • 是的,我害怕那个。我希望有更好的方法?
猜你喜欢
  • 2012-11-04
  • 2011-05-11
  • 2011-06-04
  • 2011-09-29
  • 1970-01-01
  • 2012-05-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多