我有一个现有的类,其中包含互斥锁保护的成员,如下所示(类 MembersNeedThreadSafe)...
// Just fake a mutex guard interface. Obviously doesn't do anything
class Mutex
{
public:
struct Guard
{
Guard(Mutex & M) { };
};
};
// This is the class I want to redesign.
class MembersNeedThreadSafe {
Mutex M;
int i;
double k;
// And a dozen more variables
public:
void SetI (int foo) { Mutex::Guard G(M); i = foo; }
int GetI (void) { Mutex::Guard G(M); return i; }
void SetK (double foo) { Mutex::Guard G(M); k = foo; }
double GetK (void) { Mutex::Guard G(M); return k; }
// And two dozen more methods
};
int main (void) {
MembersNeedThreadSafe bar;
bar.SetI(5);
bar.SetK(6.0);
double d = bar.GetK();
return 0;
}
我想将MembersNeedThreadSafe类重构为更像这样的设计,但它无法编译,提示非静态数据成员的无效使用。
template <typename T, Mutex & M> class LockedVar {
typedef LockedVar<T, M> my_type;
T value;
public:
void Set(T const & foo) { Mutex::Guard G(M); value = foo; }
T const & Get (void) { Mutex::Guard G(M); return value; }
};
// I want the class to look like this...
class MembersNeedThreadSafe {
Mutex M;
public:
LockedVar <int, M> i;
LockedVar <double, M> k;
// And a dozen more variables
};
// This allows the code to run.
int main (void) {
MembersNeedThreadSafe bar;
bar.i.Set(5);
bar.k.Set(6.0);
double d = bar.k.Get();
return 0;
}
那么...如何重构第一个代码块的 MembersNeedThreadSafe
类,这样我就不必为每个成员编写冗余的 getter 和 setter 方法?
附录: 我知道我可以使用这样的设计...
template <typename T> class LockedVar {
typedef LockedVar<T> my_type;
T value;
Mutex & M;
public:
LockedVar (Mutex & foo) : M(foo) { }
void Set(T const & foo) { Mutex::Guard G(M); value = foo; }
T const & Get (void) { Mutex::Guard G(M); return value; }
};
但是当我这样做时,我的编译器(gcc 4.8.2)中的 sizeof(int) == 4,而 sizeof(LockedVar) == 16,这给我带来了一种危险信号。看来我应该能够通过使用互斥体作为模板参数来解决这个问题,并且我想知道如果可能的话如何做到这一点。
最佳答案
另一个选择是稍微修改一下LockedVar
:
template <typename T> class LockedVar {
typedef LockedVar<T> my_type;
T value;
public:
void Set(T const & foo, Mutex & M ) { Mutex::Guard G(M); value = foo; }
T const & Get (Mutex & M) { Mutex::Guard G(M); return value; }
};
此外,如果您一遍又一遍地重复该内容,尽管它可能看起来不太好看,但您可以创建一个宏:
#define IMPL_SET_GET( t, x ) \
t x; \
void Set##x (int foo) { Mutex::Guard G(M); x = foo; } \
int Get##x (void) { Mutex::Guard G(M); return x; }
// This is the class I want to redesign.
class MembersNeedThreadSafe {
Mutex M;
// And a dozen more variables
public:
IMPL_SET_GET( int, i );
IMPL_SET_GET( int, k );
// And two dozen more methods
};
关于c++ - 如何重构多余的 getter/setter 方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24013702/