【问题标题】:How to only allow a value from a predefined set of constants?如何只允许预定义常量集中的值?
【发布时间】:2015-03-24 23:44:04
【问题描述】:

我有 color 类模板,上面有一些 typedefs,还有一堆颜色常量:

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&lt;uint16_t&gt; 类的其他实例,而不仅仅是预定义的 guicolor 常量,这是不可取的,因为您应该只能使用 GUI 使用的预定义颜色集。

我可以将guicolor 设为color16 的子类,但值得/好的做法,因为我不会向该类添加任何其他功能,仅将其用作与其他color16 实例区分开来的名称?有没有其他解决方案?

【问题讨论】:

  • 如果你是为了解决问题而不是专门学习你的问题的答案,你可能应该详细说明你的限制;不清楚为什么其他实例不受欢迎,也不清楚为什么您不使用enum
  • @Hurkyl 我没有使用enum,因为你不能拥有一个类类型的enum。任何想法我还应该添加什么?我想我已经在问题中包含了所有限制条件。
  • 您可以更改您的函数以接收枚举并在内部执行转换为color
  • 详细信息与问题标题不符。并不是您只想允许 typedef,而是您只想允许某些值。请编辑。
  • 不,也可以是 an additional functionality to that classuse it as a name to differentiate from other color16 instances。只是子类它。 (*)

标签: c++ class typedef


【解决方案1】:

虽然 cmets 中的建议可能是一些可能的选择,但我知道另一个技巧。

我们可以将guicolor 定义为typedef 或子类,而不是使用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

【讨论】:

  • 私有构造函数 + 类内静态实例化,好技巧!谢谢,总有一天会派上用场的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-11-27
  • 2015-02-15
  • 1970-01-01
  • 2017-07-20
  • 2019-08-12
  • 1970-01-01
  • 2012-01-01
相关资源
最近更新 更多