2012-09-11 89 views
3

比方說,我有一個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); 
} 

對於這個測試模板,內部必須是我的代碼訪問。在製作過程中,我想將其隱藏起來。

我使用msvc 11(Visual Studio 2012),所以我可以訪問一些C++ 11功能和元編程結構。

+4

'_T'絕對不是一個好用的名字。它被保留用於實現,特別是這一個,因爲我知道它正在用作一個宏來根據您的程序是否使用寬字符的東西來擴展字符串。 – chris

+0

好貼士@chris。我以此爲例,在模板中我幾乎更具體,但這很好理解。 – jmacdonagh

+1

如果你有興趣,http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier – chris

回答

4

您可以從主類繼承的測試幫手,幫助你宣佈朋友,然後宣傳你有興趣公開的元素:

#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; 
} 
+0

這是一個非常接近我解決的解決方案。我剛開始使用GoogleTest,遇到了私人會員問題。我沒有意識到他們已經提供瞭解決方案:http://code.google.com/p/googletest/wiki/AdvancedGuide#Private_Class_Members – jmacdonagh

1

你可以用類模板專業化做到這一點,但是,它意味着你需要修改這兩套代碼,當你做出改變:

#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; 
} 
+0

是的,我很害怕這一點。我希望有更好的方法? – jmacdonagh