- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
假设您正在编写一个库,为一个类提供某种“类型”参数。对于这个可能使用枚举:
namespace MyLib {
class Event {
public:
enum EventType { TYPE1, TYPE2, ... };
Event(EventType _type) : type(_type) { }
private:
EventType type;
}
}
然后实例化:
new MyLib::Event(Event::TYPE1);
到目前为止还不错。但是,如果您希望用户能够扩展事件类型列表怎么办?如果类型属性是枚举,这是不可能的。
低质量的可能性包括要求他们#define
自定义事件名称,或者简单地使用字符串,尽管这些似乎都不是最佳选择。
有通用的解决方案吗?
一个建议是使用 struct EventType
返回枚举中指定范围内的值。然而,虽然这解决了编译器安全问题,但它没有解决添加命名类型的问题——它需要用户将这些添加到全局范围。
解决后者而不是前一个问题的一种可能性是将 EventType typedef 为一个完整类型,并留给用户将自定义类型添加到库的命名空间或他们自己的命名空间。提供唯一值的工厂方法可以作为事件的一部分提供:
#include <iostream>
#include <vector>
namespace MyLib {
namespace EventType {
typedef int T;
enum { TYPE1, TYPE2, Count};
}
class Event {
public:
Event(EventType::T _type) : type(_type) { }
EventType::T type;
static EventType::T registerType() { return _typeid++; }
private:
static int _typeid;
};
}
MyLib::EventType::T MyLib::Event::_typeid = EventType::Count;
// The user can then add types, including to the library's namespace
// (which may or may not be a good idea)
namespace MyLib { namespace EventType {
MyLib::EventType::T MYTYPE = MyLib::Event::registerType();
} }
int main() {
MyLib::Event ev1(MyLib::EventType::TYPE2);
MyLib::Event ev2(MyLib::EventType::MYTYPE);
std::cout << ev1.type << std::endl;
std::cout << ev2.type << std::endl;
return 0;
}
输出:
1
2
虽然这在技术上并未将参数限制为一组已注册的类型,但 typedef 和命名空间在 IDE 中的构造函数定义和自动建议中提供了一个有用的语法提示,并且它可以防止用户类型不得不污染全局范围,这可能是更大的问题。
有没有更好的方法来指定一个有限的、经过编译器检查但用户可扩展的值集作为类或函数/方法的类型参数?
最佳答案
我认为最好的办法是简单地将事件类型作为普通整数类型,使用枚举来定义内置类型,并提供用户定义的最小值和最大值,用户可以在这些值之间创建自己的整数值有一个单独的枚举器。然后,您只需使用断言来确保基本事件不会尝试处理未知事件类型。
编辑:请注意,具有某些可以理解的类型和一些不可以理解的类型的基事件类可能是脆弱的,除非它只是保存数据供子类稍后再次挑选。即使在那种情况下,考虑替代设计可能会更好。您能否详细说明事件类型设置后如何使用?
EDIT2:我想我现在理解得更好了,事件存储事件类型,事件消费者可以从事件中检索它。如果消费者了解扩展事件类型,它可以进行适当的处理,否则委托(delegate)、断言或简单地不进行任何操作。鉴于此,我认为使用完整的事件类型似乎不错。
关于c++ - C++ 中具有用户可扩展类型参数的类型化类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11905757/
简而言之:我想从可变参数模板参数中提取各种选项,但不仅通过标签而且通过那些参数的索引,这些参数是未知的 标签。我喜欢 boost 中的方法(例如 heap 或 lockfree 策略),但想让它与 S
我可以对单元格中的 excel IF 语句提供一些帮助吗? 它在做什么? 对“BaselineAmount”进行了哪些评估? =IF(BaselineAmount, (Variance/Baselin
我正在使用以下方法: public async Task Save(Foo foo,out int param) { ....... MySqlParameter prmparamID
我正在使用 CodeGear RAD Studio IDE。 为了使用命令行参数测试我的应用程序,我多次使用了“运行 -> 参数”菜单中的“参数”字段。 但是每次我给它提供一个新值时,它都无法从“下拉
我已经为信用卡类编写了一些代码,粘贴在下面。我有一个接受上述变量的构造函数,并且正在研究一些方法将这些变量格式化为字符串,以便最终输出将类似于 号码:1234 5678 9012 3456 截止日期:
MySql IN 参数 - 在存储过程中使用时,VarChar IN 参数 val 是否需要单引号? 我已经像平常一样创建了经典 ASP 代码,但我没有更新该列。 我需要引用 VarChar 参数吗?
给出了下面的开始,但似乎不知道如何完成它。本质上,如果我调用 myTest([one, Two, Three], 2); 它应该返回元素 third。必须使用for循环来找到我的解决方案。 funct
将 1113355579999 作为参数传递时,该值在函数内部变为 959050335。 调用(main.c): printf("%d\n", FindCommonDigit(111335557999
这个问题在这里已经有了答案: Is Java "pass-by-reference" or "pass-by-value"? (92 个回答) 关闭9年前。 public class StackOve
我真的很困惑,当像 1 == scanf("%lg", &entry) 交换为 scanf("%lg", &entry) == 1 没有区别。我的实验书上说的是前者,而我觉得后者是可以理解的。 1 =
我正在尝试使用调用 SetupDiGetDeviceRegistryProperty 的函数使用德尔福 7。该调用来自示例函数 SetupEnumAvailableComPorts .它看起来像这样:
我需要在现有项目上实现一些事件的显示。我无法更改数据库结构。 在我的 Controller 中,我(从 ajax 请求)传递了一个时间戳,并且我需要显示之前的 8 个事件。因此,如果时间戳是(转换后)
rails 新手。按照多态关联的教程,我遇到了这个以在create 和destroy 中设置@client。 @client = Client.find(params[:client_id] || p
通过将 VM 参数设置为 -Xmx1024m,我能够通过 Eclipse 运行 Java 程序-Xms256M。现在我想通过 Windows 中的 .bat 文件运行相同的 Java 程序 (jar)
我有一个 Delphi DLL,它在被 Delphi 应用程序调用时工作并导出声明为的方法: Procedure ProduceOutput(request,inputs:widestring; va
浏览完文档和示例后,我还没有弄清楚 schema.yaml 文件中的参数到底用在哪里。 在此处使用 AWS 代码示例:https://github.com/aws-samples/aws-proton
程序参数: procedure get_user_profile ( i_attuid in ras_user.attuid%type, i_data_group in data_g
我有一个字符串作为参数传递给我的存储过程。 dim AgentString as String = " 'test1', 'test2', 'test3' " 我想在 IN 中使用该参数声明。 AND
这个问题已经有答案了: When should I use "this" in a class? (17 个回答) 已关闭 6 年前。 我运行了一些java代码,我看到了一些我不太明白的东西。为什么下
我输入 scroll(0,10,200,10);但是当它运行时,它会传递字符串“xxpos”或“yypos”,我确实在没有撇号的情况下尝试过,但它就是行不通。 scroll = function(xp
我是一名优秀的程序员,十分优秀!