将虚函数从基类转发到具有相同签名的另一个虚函数

时间:2014-01-12 21:31:00

标签: c++ templates copy polymorphism covariance

我试图在我的一些类中支持复制函数,为此我创建了一个基类(一个接口)。但是除了那个类,我还有另一个继承它的类,需要覆盖“copy”函数并提供一个新的返回类型。我复制类的方法是使用包装器类在不再使用时自动删除指向新分配对象的指针。它是一个模板化的类,不符合协变型。我刚刚描述的内容看起来很像这样:

template <T>
struct BASE {
    virtual PTR<BASE> copy() const = 0;
};

template <Y>
struct DERIVED : public BASE<Y> {
     virtual PTR<DERIVED> copy() const = 0; // ERROR: PTR<DERIVED> not a covarient type to PTR<BASE>.
};

知道这在C ++中是不合法的,我想知道我是否可以做类似的事情,例如:

template <T>
struct DERIVED : public BASE<T> {
    virtual PTR<DERIVED> DERIVED::copy() const = 0; // Derived classes should override this function and act as if "PTR<BASE<T>> BASE<T>::copy() const" does not exist.

    private: // hide function so that "PTR<DERIVED>" function is called, but when dealing with the base class call the following function.
    PTR<BASE<T>> BASE<T>::copy() const {
         return PTR<BASE<T>>((BASE<T>*)DERIVED::copy()->GetAndRelease()); // Convert the "PTR<DERIVED>" object to a "PTR<BASE<T>>" object.
    }
};

上面的代码无法编译,因为在类中定义它时,您无法为该类命名。 EX:在类中定义一个函数时不能做“DERIVED :: copy”,至少G ++在我这样做时给了我一个错误。值得一提的是,提到的“PTR”类的工作原理如下:

template <T>
struct PTR {
    PTR(T* ptr); // set the pointer to the data;
    ~PTR(); // destroy the object pointed to by "ptr";

    T* get(); // get the pointer to the data;
    T* GetAndRelease(); // just to simplify the example, this function returns the pointer and makes it so that the class does not delete the pointer when it is deconstructed.

    private:
    T* ptr;
}

1 个答案:

答案 0 :(得分:0)

您不能根据返回类型重载。简单的解决方案是使copy()函数成为virtual接口,而是让它只调用virtual接口:

class Base {
    Base* do_copy() const = 0;
public:
    smart_ptr<Base> copy() const { return smart_ptr<Base>(this->do_copy()); }
};
class Derived {
     Derived* do_copy() const { return new Derived(*this); }
public:
     smart_ptr<Derived> copy() const { return smart_ptr<Derived>(this->do_copy()); }
};

不使虚拟函数公开的习惯用法在标准库中非常一致地使用(我认为例外是std::exception::what())。它还可以方便地反对隐藏其他重载的覆盖问题(例如,请参阅put()的{​​{1}}和do_put()成员。)