2011-09-23 44 views
1

我有2類:是否有可能在C++中禁止在編譯時調用某個函數?

class Entity { 
    void addChild(Entity* e); 
}; 

class Control : public Entity { 

}; 

我想要做的是不允許添加控件作爲東西的孩子,這不是一個控制。因此,舉例來說:

Control c; 
Entity e; 
e.addChild(c); // This line would throw an error (at compile time if possible); 

我想到的是增加這實體的第一件事:

void addChild(Control* c){ 
    assert(false); 
}; 

注:實體和控制都是抽象類,但兩者有很多子類。

但是有什麼辦法可以在編譯時得到錯誤嗎?

+1

我建議只是重新設計你的類層次結構,這樣你就不會想要在派生類中使用的固有函數。 – sashang

+0

也許你可以用'Entity'作爲*抽象類*,那麼就不可能實例化一個Entity對象。 – Simon

+1

我與sashang:如果你需要明確禁止使用派生類作爲基類,那麼很有可能公共繼承不是你想要做的。公有繼承的要點是你可以使用派生類作爲基類。如果你不得不禁止它,這可能是你的課堂布局和設計結構中的一個問題。 –

回答

5

您可以聲明函數,但不要實現它。如果您嘗試使用它,會導致鏈接器錯誤。

+0

如果將控件添加爲基類(實體)指針,它仍然無法幫助。 –

+0

的確如此,但這更多的是需要重新設計的基本問題。 – Mysticial

2

void addChild(Control c){ assert(false); };

但是有什麼辦法可以在編譯時得到錯誤嗎?

你可以使用static_assert如果您的實現有一定的C++ 11的支持,或BOOST_STATIC_ASSERT將在任何實施工作。不過,我建議你重新設計你的層次結構。另請注意,您在建議的addChild的定義中混合了指針和對象。

2

在C++ 0x中,你尋求的機制確實是可能的。

class Entity { 
public: 
    void addEntity(Entity*); 
    void addEntity(Control*) = delete; 
}; 

它不工作,你所期望的吧!

int main() { 
    Entity e; 

    Control c; 
    e.addEntity(&c); // ERROR 

    Entity& ec = c; 
    e.addEntity(&ec); // OK 
} 

正如其他人所建議的,您的使用案例很腥。如果您不希望Control類作爲Entity傳遞,請刪除繼承關係。如果保持繼承關係,那麼無論何時期望Entity,都可以傳遞Control

2

隨着模板專業化的一點點,它可以做些什麼。但是我唯一可以做這件事的方法是在子元素本身上添加「addChild」方法(重命名爲「AttachToParent」)。並通過引用而不是通過指針傳遞。模板專業化很難!

class Entity 
{ 
public: 
    void AddChild(Entity* pChild); 
}; 

class Control : public Entity 
{ 

public: 
    template <typename T> 
    void AttachToParent(T& parent) 
    { 
     parent.You_are_trying_to_attach_Control_to_something_not_a_Control(); 
    } 

    template <> 
    void AttachToParent<Control>(Control& parent) 
    { 
     parent.AddChild(this); 
    } 
}; 



int main(int argc, char** argv) 
{ 
    Entity eParent; 
    Entity eChild; 
    Control cChild1; 
    Control cChild2; 

    eParent.AddChild(&eChild); // legal 

    cChild2.AttachToParent(cChild1); // allowed 
    //cChild1.AttachToParent(eParent); // uncomment this line and a compile error will occur 

    return 0; 
} 
相關問題