在下面的代码中,我尝试从其父类(Building)访问类(Apartment)的私有字段(contamination_levels)。在这种情况下,我认为朋友函数无法提供帮助,因为我正在使用继承,但是如果我做错了,请更正我。
template<typename T>
struct Building {
operator uint32_t() const {
return (static_cast<T const *>(this)->contamination_levels);
}
void operator=(uint32_t const cl) {
static_cast<T*>(this)->contamination_levels = cl;
}
};
struct Apartment: Building<Apartment> {
using Building<Apartment>::operator=;
public:
Apartment(uint32_t const c = 0) : contamination_levels(c) {}
uint32_t getAContLevel() {
return roomA;
}
uint32_t getBContLevel() {
return roomB;
}
uint32_t getCContLevel() {
return roomC;
}
private:
union {
struct
{
uint32_t roomA : 4;
uint32_t : 4;
uint32_t roomB : 4;
uint32_t : 4;
uint32_t roomC : 8;
uint32_t : 8;
};
uint32_t contamination_levels;
};
};
int main() {
Apartment Bayview2000 = 0x74352;
uint32_t cont_level = Bayview2000;
}
main()的第2行运行时,它将调用在Building类中定义的强制转换运算符uint32_t()。从建筑物访问专用字段污染级别时会出现问题。
在所有字段都公开之前,处理私有字段不是问题。
答案 0 :(得分:2)
为什么不尝试朋友?有用。测试它,您将看到它。
template<typename T>
struct Building
{
operator uint32_t() const
{
return ( static_cast<T const *>( this )->contamination_levels );
}
void operator=( uint32_t const cl )
{
static_cast<T*>( this )->contamination_levels = cl;
}
};
struct Apartment : Building<Apartment>
{
// friend works.
template<typename T> friend struct Building;
using Building<Apartment>::operator=;
public:
Apartment( uint32_t const c = 0 ) : contamination_levels( c )
{
}
uint32_t getAContLevel()
{
return roomA;
}
uint32_t getBContLevel()
{
return roomB;
}
uint32_t getCContLevel()
{
return roomC;
}
private:
union
{
struct
{
uint32_t roomA : 4;
uint32_t : 4;
uint32_t roomB : 4;
uint32_t : 4;
uint32_t roomC : 8;
uint32_t : 8;
};
uint32_t contamination_levels;
};
};
int main()
{
Apartment Bayview2000 = 0x74352;
uint32_t cont_level = Bayview2000;
return 0;
}
但是更好的方法是使用公共的get和set函数(如果适合的话)(如果您不想隐藏这些功能):
template<typename T>
struct Building
{
operator uint32_t() const
{
return ( static_cast<T const *>( this )->getContaminationLevels() );
}
void operator=( uint32_t const cl )
{
static_cast<T*>( this )->setContaminationLevels( cl );
}
};
struct Apartment : Building<Apartment>
{
using Building<Apartment>::operator=;
public:
Apartment( uint32_t const c = 0 ) : contamination_levels( c )
{
}
uint32_t getAContLevel()
{
return roomA;
}
uint32_t getBContLevel()
{
return roomB;
}
uint32_t getCContLevel()
{
return roomC;
}
uint32_t getContaminationLevels() const
{
return contamination_levels;
}
uint32_t setContaminationLevels( uint32_t cl )
{
contamination_levels = cl;
}
private:
union
{
struct
{
uint32_t roomA : 4;
uint32_t : 4;
uint32_t roomB : 4;
uint32_t : 4;
uint32_t roomC : 8;
uint32_t : 8;
};
uint32_t contamination_levels;
};
};
int main()
{
Apartment Bayview2000 = 0x74352;
uint32_t cont_level = Bayview2000;
return 0;
}