2016-04-24 66 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