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

Calling a virtual function of the base class in a non virtual function of the base class

本文关键字:函数 基类 调用      更新时间:2023-10-16

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

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;
}

是的,这将工作。你自己试过吗?

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

是。当您需要操作符实现的虚函数行为时使用此技术:您根据虚(或抽象)函数定义操作符,并让专门化决定如何实现该函数。

的例子:

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不同的实现。

可以。这允许您在基类中提供通用流,其详细信息在其子类中专门化。