在基类的非虚函数中调用基类的虚函数

时间:2013-03-13 17:27:52

标签: c++

在基类的非虚函数中调用派生类中实现的基类的虚函数是否正确。像

这样的东西
class A
{
 virtual void func1() = 0;

 void func2()
 {
   func1();
 }
};

class B : public A
{
 virtual void func1()
 {
   //do something here;
 }
};

int main()
{
 A* obj = new B;
 obj->func2();
 return 0;
}

4 个答案:

答案 0 :(得分:2)

是的,这会有效。你自己尝试过吗?

答案 1 :(得分:2)

它不仅是一种众所周知且有效的解决方法,但如果内联func2,则可能意味着与直接调用内部函数相比,没有额外的开销。显然,有时候整个目的是在func1内做一些事情,然后在中间或末尾调用func2,但是在额外工作很少的情况下,“额外功能层”可能消失了。

答案 2 :(得分:1)

是的,没关系。这允许您在基类中提供公共流,其详细信息专门针对其子类。

请参阅template method

答案 3 :(得分:1)

是。当您需要用于运算符实现的虚函数行为时,将使用此技术:您根据虚拟(或抽象)函数定义运算符,并让特化决定如何实现该函数。

示例:

class base
{
// yada yada yada
    base& operator=(const base& other) { return assign(other); }
protected:
    virtual base& assign(const base& other) = 0; // specializations will decide
                                                 //  what assignment means
};

编辑:该技术的另一个用途是允许类的特化仅控制更复杂操作的部分:

class database
{
public:
    void execute(const std::string& query)
    {
        begin_transaction(); // in practice, this should be RAII
        connection_.execute(query);
        end_transaction();
    }
protected:
    virtual void begin_transaction() = 0;
    virtual void end_transaction() = 0;
private:
    whatever &connection_;
};

在数据库专业化中,假设mysql_database::begin_transaction的实现与sqlite_database::begin_transaction不同。