2016-04-24 61 views
2

我正在教一个C++课程,并且在其中一个项目中,学生需要编写一个Robot类的代码。OOP:没有静态成员的类或完全重新设计

机器人的构造函数是固定的,实例是由学生无法修改的函数创建的。然而,其余的课程设计只是一个练习。

我想确保Robot实例不能轻松地在彼​​此之间共享信息。如果学生想分享信息,他可以创建类的静态成员,或者在类的实现中使用静态变量来存储关于每个实例的信息。 也可能有其他方式利用该语言来“作弊”(例如使用套接字写入文件...)。

有什么办法来检查这种滥用(例如存在静态成员)吗?在这一点上,我愿意接受任何建议。 我应该考虑一个完整的重新设计,让每个实例“生活在一个完全不同的世界”,以防止它们彼此通信? 预防是否是一个根本不可能的问题,我应该只是警告他们这种行为的严重影响?

谢谢。

编辑: 我问这个问题的原因不是为了减轻分级。我计划创建一个自动化平台,让学生们可以提交他们的代码并让他们与对方竞争。在这种情况下,我将无法在发布之前读取和验证代码。 我想防止“简单”滥用(例如静态成员),并认为更多涉及滥用行为将不会如此常见。

因此,我的问题确实是:有没有一种方法可以以编程方式防止学生拥有静态成员(模板破解或某事)或我应该重新设计类。谢谢

+0

'grep static code.cpp' – user657267

+0

是的,我已经想到了这个:) – elvadrias

+0

控制对类成员的访问是在类级而不是单个对象。由于您正在教授课程,因此只要说明如果学生使用除非静态成员以外的任何内容来在“Robot”实例之间进行交流,就会被标记。当然,这要求您检查代码,而不是简单地自动检查代码。 – Peter

回答

0

有什么办法来检查这种滥用(例如存在一个静态成员)?

是:读取代码。

可能有一些方法可以通过语言黑客和/或在生成的代码上运行解析器来自动禁止此操作。但一般情况下,这些解决方案将是方式如果它们正常工作,则会过度使用。

所以,只要做我们在业界做的事情:用你的眼睛来审查代码,并做相应的标记!希望你在决定给学生什么标记之前已经阅读了代码,所以这应该不是你的牙齿。

只记得事先告诉你的学生你不想看到这样的骇客。

+0

我更新了问题!我的目标不是简化分级,而是要真正防止最容易发生的虐待事件。 – elvadrias

+0

@elvadrias:我的回答站立。只需阅读代码。我不会假装我100%肯定没有办法自动提出你的建议,但是我知道它会很糟糕,(b)不值得。我很欣赏你试图达到的目标,但实际上,你必须让人类的认知能力承担任何这样的问题。 –

+0

是的,我同意彻底检查每种滥用行为可能会矫枉过正。然而,一些给出的建议非常简单,可能足以阻止智能设备。在任何情况下,代码将在分级时检查,但不在网上提交时检查,我不希望项目成为巨魔巨星;) – elvadrias

0

有什么办法来检查这种滥用(例如存在静态成员)吗?

的种类。在C++中以编程方式,没有 - C++没有反射,所以没有办法编写类型trait has_static_member<T>

你基本上需要的是你自己的C++解析器来生成一个AST,然后你可以通过步行来确定是否存在static成员。我不建议尝试编写自己的C++ AST分析器。谢天谢地,你可以使用clang's。其中也可以使用in Python。现在只需要弄清楚如何使用它来给你想要的答案。

举个例子,

class Robot { 
public: 
    Robot(); 
    void foo(); 
private: 
    static int bar; 
    double quux; 
}; 

当通过ast-dump命令运行给我:

|-CXXRecordDecl 0x491c9d8 <main.cpp:1:5, line:8:5> line:1:11 class Robot definition 
| |-CXXRecordDecl 0x491caf0 <col:5, col:11> col:11 implicit referenced class Robot 
| |-AccessSpecDecl 0x491cb80 <line:2:5, col:11> col:5 public 
| |-CXXConstructorDecl 0x491cc50 <line:3:9, col:15> col:9 Robot 'void (void)' 
| |-CXXMethodDecl 0x496f900 <line:4:9, col:18> col:14 foo 'void (void)' 
| |-AccessSpecDecl 0x496f9a8 <line:5:5, col:12> col:5 private 
| |-VarDecl 0x496f9e0 <line:6:9, col:20> col:20 bar 'int' static 
| `-FieldDecl 0x496fa50 <line:7:9, col:16> col:16 quux 'double' 

所以你要找VarDecl S中的类成员(因为非静态成员是FieldDecl s)。

+0

谢谢,这是一种非常简单的方法,处理脚本。这似乎比简单的grep静态更健壮。 – elvadrias