我有color
类模板,上面有一些typedef
,还有一堆颜色常量:
template<typename T>
class color
{
public:
color(T data) : data(data) {}
// other functions...
private:
T data;
};
typedef color<uint16_t> color16;
typedef color<uint32_t> color32;
typedef color16 guicolor;
const guicolor WHITE = 0xFFFF;
const guicolor BLACK = 0x000F;
// other colors...
我还有一些 应该采用预定义的guicolor
常量之一的函数,例如:
void foo(guicolor Color) { ... }
但是,foo
也接受color<uint16_t>
类的其他实例而不仅仅是预定义的guicolor
常量,这是不可取的,因为您应该只能使用预定义的一组颜色GUI使用。
我可以使guicolor
成为color16
的子类,但值得/良好实践,因为我不会向该类添加任何其他功能,只能将其用作名称以区别于其他color16
个实例?还有其他解决方案吗?
答案 0 :(得分:1)
虽然评论中的建议可能是一些可能的选择,但我知道另一个技巧。
我们可以将它定义为一个单独的类,而不是使用guicolor
或子类化定义typedef
,而不是使用3个技巧。
class guicolor
{
private:
uint16_t data;
private: // Trick 1: private constructor!
guicolor(uint16_t data) : data(data) {}
public: // Trick 2: custom conversion!
operator color16() const
{
return color16(this->data);
}
public: // Trick 3: static members!
static const guicolor White;
static const guicolor Black;
};
// Static members need to be *declared* in the class, and *defined* outside.
const guicolor guicolor::White = 0xFFFF;
const guicolor guicolor::Black = 0x0000;
然后,foo
函数就是你所写的。
void foo(guicolor c) { ... }
接下来是用法。
color16 some_color_1 = 0xF000; // Normal
color16 some_color_2 = guicolor::White; // guicolor object is implicitly convertible to color16
guicolor some_guicolor_1 = 0x1234; // Compilation error as expected, due to private constructor.
guicolor some_guicolor_2 = guicolor::White; // Compilation pass, due to the pre-defined static member and compiler generated public copy constructor.
foo(some_color_1); // Compilation error as expected
foo(some_guicolor_2); // Compilation pass