基类和派生类的虚拟插入运算符重载

时间:2018-06-22 02:45:34

标签: c++ pointers inheritance polymorphism operator-overloading

有人可以解释一下如何确保从基本类型的指针到派生对象而不是基本函数的调用派生函数吗...

此外,virtual和override关键字是否是实现此目的的最佳实践?

我以前在每个类中用关键字friend定义了每个重载;但是调用了基本函数来指向派生对象的基本指针。

int main()
{  
    // contrived example ...
    base* ptr_derived = new derived();
    std::cout << *ptr_derived;

    delete ptr_derived;
}
class base 
{
    virtual std::ostream& operator<<(std::ostream output)
    {
        output << // base details... 
        return output;
    }
};

class derived : public base
{
    std::ostream& operator<<(std::ostream output) // override?
    {
        output << // derived details...
        return output;
    }
};

2 个答案:

答案 0 :(得分:2)

虚拟函数通过通过称为vtable的指针调用正确的函数来工作。因此,this的一些偏移量提供了指向vtable的指针,而vtable的一些偏移量则提供了该对象实际类型的函数地址。

但是,如果将对象插入流中,而operator<<的重载将无法(直接)实现此功能。虚拟函数必须是成员函数-但是当您重载成员函数时,其 left 操作数必须是要为其提供重载的类型的对象。也就是说,对于重载的成员函数,a << b作为a.operator<<(b);被调用。对于无法插入的流,因为左操作数始终是流,而不是要插入到流中的类型。

要解决这个问题,您必须使操作员本身成为朋友(从来都不是成员)。

要获得虚拟行为,您必须调用一个虚拟成员函数:

class base { 
public:
    virtual std::ostream &write(std::ostream &os) const { 
        // write myself to the passed stream
        return os;
    }

    friend std::ostream &operator<<(std::ostream &os, base const &b) { 
       return b.write(os);
    }
};

class derived : public base {
public:
    std::ostream &write(std::ostream &os) const override { 
        // write myself to the passed stream
        return os;
    }
};

现在,将为正确的类型调用重载运算符。反过来,它只是为实际传递的对象(basederived或其他一些派生类,如果您选择创建一个)调用正确的虚函数。

答案 1 :(得分:1)

@echo off systeminfo | findstr /c:"Host Name" /c:"Domain" /c:"OS Name" /c:"OS Version" /c:"System Manufacturer" /c:"System Model" /c:"System type" /c:"Total Physical Memory" /c:"Available Physical Memory">"getPCinfo.txt" FOR /F "tokens=1,2 delims==" %%G IN ('wmic bios get serialnumber /value ^|find /I "serialnumber"') DO >>"getPCinfo.txt" echo %%G : %%H 必须是非成员函数,您不能使其成为operator<<。您必须制作另一个virtual成员函数,并在virtual中进行调用才能使运行时调度工作。例如

operator<<