2010-06-04 62 views
2

部分使用內存誰不都有一個共同祖先的進程之間共享。我們將C++對象放置在這個共享內存中。關於這些對象的方法或者在頭中內聯,或者在鏈接到相應進程中的對象庫中不在行中。在C++對基類的任何方法來在diallow所有派生類的虛方法?我們的系統

經常通過新加入到系統中作出的錯誤是在某處引入虛擬方法。這可以確保系統崩潰,因爲無法確保VT(虛擬表)駐留在每個進程中的相同地址。

因此我不知道是否有我使編譯器,如果有人試圖引入一個虛擬的方法來發出錯誤的方式。類似於使複製和賦值構造函數類似於禁止複製語義。

+7

答案並不是將C++對象放置在共享內存中 - 這總是以淚流滿。將原始數據放入共享內存中 - 而不是對象。 – 2010-06-04 12:53:28

+2

@Neil - 但Boost.Interprocess是如此酷... – 2010-06-04 13:07:31

+0

@Neil - 這是一個「讓我們用洗澡水扔掉嬰兒」的態度。撤消基於VT的多態性不會使C++對象變得毫無價值。而且,在增加複雜性之前,不得不教會新手共享內存的含義,這些複雜性我們不得不承擔共享內存中的原始數據。 – 2010-06-06 14:53:12

回答

1

你可以#define virtual Something_else當有人使用虛擬這將使編譯器錯誤,但他們沒有任何意義沒有更多的工作。

+1

贏得解決方案。 '#define virtual void fail(){static_assert(false,「No virtual functions allowed!」);}' – Puppy 2010-06-04 13:15:06

+2

Counter:'#undef virtual' – Dashogun 2010-06-04 13:18:48

3

Boost.TypeTraits提供了一個is_polymorphic特質,但您可能必須做一些技巧才能將它應用到需要的任何地方。 (例如,在基類上調用is_polymorphic不會告訴您派生類是否引入了虛函數。)

根據您的構建系統和可用工具,您可能能夠在其中引入檢查。例如,如果我對GCC創建的對象文件運行nm -C,我看到下面的輸出爲一個簡單的測試類的虛函數:

0000000e T TestMe::TestMe() 
00000078 T TestMe::~TestMe() 
00000000 V typeinfo for TestMe 
00000000 V typeinfo name for TestMe 
00000000 V vtable for TestMe 

所以我就可以建立我生成文件(或其他)運行nm -C在所有目標文件上,並且如果有任何包含vtable for的話會引發錯誤。

4

在提交給你的資料庫,
對於以這種方式共享的每個班級,
如果字虛擬出現的文件
無法提交,發送電子郵件到高級開發人員,以及碼頭的薪酬在違規派對。

4

當一個虛擬函數出現在具有非虛擬析構函數的類中時,GCC(也可能是其他)會發出警告。

爲所有的共享類提供一個顯式的非虛擬析構函數(無所事事?),並將警告視爲錯誤。

+0

雖然這不會阻止新手開發者添加他自己的虛擬析構函數。 。 – 2010-06-04 15:09:13

+0

新手可以將基類析構函數更改爲虛擬 - 您需要!評論!那裏。他/她無法將虛擬析構函數添加到派生類,而不會觸發相同的警告。 – Arkadiy 2010-06-04 18:29:05

+0

我做了一個快速測試,看起來像添加虛擬析構函數到派生類不會觸發警告,至少對於GCC 4.3.2來說。然而,這將是一個奇怪的做法,所以你是對的,一個評論!應該阻止大多數濫用。 – 2010-06-04 18:50:09

2

可以使用is_polymorphicBOOST_STATIC_ASSERT的組合來創建編譯器錯誤,當有人向類中添加虛擬功能時。將BOOST_STATIC_ASSERT調用放入您的類的實現文件中。

#include <boost/type_traits/is_polymorphic.hpp> 
#include <boost/static_assert.hpp> 
#include <cassert> 

class A 
{ 
public: 
    /*virtual*/ void magic() {}; // making this virtual causes a compile error and a runtime error 
}; 

using namespace boost; 
int main() 
{ 
    assert(is_polymorphic<A>::value == false); 
    BOOST_STATIC_ASSERT(is_polymorphic<A>::value == false); 
} 
0

這是一個(Visual Studio 2015)C++ 11對老問題的回答。它與Boost的答案類似。

#include <type_traits> 

class foo 
{ 
}; 

static_assert(!std::is_polymorphic<foo>::value, "Virtual not allowed in this class.");