C ++:如何用通用返回类型定义虚函数?

mba*_*i23 4 c++ oop

我试图在C ++中定义一个基类,该基类具有要由子类实现的纯虚拟方法。

我想在基类中为基本类型定义setter和getter函数,但我希望派生类能够确定getter和setter的基本类型。例如,我的基类如下所示:

    class Value
    {
    public:
        Value();
        template <class T>;
        virtual T getValue() = 0;
        virtual void setValue(T val) = 0;
    }
Run Code Online (Sandbox Code Playgroud)

我的孩子班级看起来像这样:

    class IntValue : public Value
    {
    public:
        IntValue();
        template <class T>
        T getValue() {return _val};
        void setValue(T val) {_val = val};
    private:
        int _val;
    }
Run Code Online (Sandbox Code Playgroud)

当然,上面的代码不起作用。关于如何实现这一目标的任何想法?提前致谢。

Bil*_*eal 6

你所要求的是不可能的。为了在vtbl(或编译器可能使用的任何类似结构)中生成正确的条目,编译器需要知道基类中具体需要哪些条目。您不能只在派生类中返回不同的类型并期望基类以这种方式“了解”它;因为这需要修改基类中函数模板的定义。

J_D 的回答中可以看到如何使用类模板(而不是函数模板)对基类进行这种修改的示例,但这仍然与您的问题描述不完全匹配,因为您不会能够创建并以多态方式处理它。Value

C++ 模板本质上是对类型的“花式查找和替换”——当编译器实例化函数模板时,它会生成一个替换了类型名的普通函数。请注意,这与 C# 或 Java“泛型”有很大不同,后者完全不同,并且依赖运行时支持和间接层来实现类似的效果。(请注意,此“查找和替换”遵循优先级规则等,与 C 预处理器宏不同:))

如果你也认真思考一下,这种模式就没有意义。在客户端,这到底是什么样子的?

class Value
{
public:
    Value();
    //Imagine if this were possible...
    template <class T>;
    virtual T getValue() = 0;
    virtual void setValue(T val) = 0;
}

class IntValue : public Value
{
public:
    IntValue();
    int getValue() {return _val};
    void setValue(int val) {_val = val};
private:
    int _val;
}

class FloatValue : public Value
{
public:
    FloatValue();
    float getValue() {return _val};
    void setValue(float val) {_val = val};
private:
    float _val;
}
Run Code Online (Sandbox Code Playgroud)

现在,你去使用这个类:

void example(Value * ptr)
{
    //What could you possibly say the type of "bar" is? There's no type that works!
    ???? bar = ptr->getValue();
    delete ptr;
}

int main()
{
    example(new IntValue());
    example(new FloatValue());
}
Run Code Online (Sandbox Code Playgroud)

因此,即使允许这样做,也没有多大意义。你总是必须一直向下转换,这意味着关键字virtual无论如何都是毫无意义的。


J_D*_*J_D 5

如果我正确理解了您的问题,请将您的代码重写为

template <class T>
class Value
{
public:
    Value();
    virtual T getValue() = 0;
    virtual void setValue(T val) = 0;
};


class IntValue : public Value<int>
{
public:
    IntValue();

    int getValue() {return _val;}
    void setValue(int val) {_val = val;}
private:
    int _val;
};
Run Code Online (Sandbox Code Playgroud)

应该管用

  • 在这种情况下,“ IntValue”不是“ Value”的子类。因此,“ virtual”关键字没有任何意义。您将无法定义一个接受“ Value *”并将其传递“ IntValue”的函数。 (4认同)