2011-04-18 106 views
0

我有一个看起来像这样一个层次结构:非虚拟接口 - 如何调用正确的虚拟功能

class Base 
{ 
public: 
    void Execute(); 
    virtual void DoSomething() = 0; 
private: 
    virtual void exec_(); 
}; 

class Derived : public Base 
{ 
public: 
    //DoSomething is implementation specific for classes Derived from Base 
    void DoSomething(); 

private: 
    void exec_(); 
}; 

void Base::Execute() 
{ 
    // do some work 
    exec_(); //work specific for derived impl 
    // do some other work 
} 

void Derived::DoSomething() 
{ 
    //impl dependent so it can only be virtual in Base 
} 


int main() 
{ 
    Derived d; 
    Base& b = d; 

    b.Execute(); //linker error cause Derived has no Execute() function?? 

} 

所以,问题是我怎么叫使用这种模式执行()当我创建一个派生使用我的基类。在我的情况下,我不想直接创建Derived,因为我有从Base派生的多个类,根据某些条件我必须选择不同的派生类。

任何人都可以帮忙吗?

+0

有人请编辑nvi的标签wiki,谢谢。 – 2011-04-18 09:04:17

+0

嗯,什么是'nvi'? – 2011-04-18 09:05:13

+0

@Konrad:http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Non-Virtual_Interface – 2011-04-18 09:05:45

回答

6

class Base 
{ 
public: 
    void Execute(); 
private: 
    virtual void exec_() {} 
}; 

class Derived : public Base 
{ 
private: 
    void exec_() {} 
}; 

void Base::Execute() 
{ 
    // do some work 
    exec_(); //work specific for derived impl 
    // do some other work 
} 

int main() 
{ 
    Derived d; 
    Base& b = d; 

    b.Execute(); 
} 

编译,链接,和我运行。

+0

模糊不清,但DoSomething是重要的,但不知道你是否为了简洁或因为它在那里是错的而丢掉了它? – 2011-04-18 09:12:27

+0

我没有见过'Base :: Execute'的实现。 +1给你,这个问题比我想象的更加微不足道。 – 2011-04-18 09:13:41

+1

@Tony:DoSomething与您的问题无关,因为它根本不遵循NVI原则。 – 2011-04-18 09:14:08

0

您应该也可能在您的基类中创建exec_()纯虚拟。然后您还需要在派生类中实现它。

0

您需要为exec_()函数编写函数定义。