2011-09-23 37 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; 
} 
相关问题