Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++;:如何定义具有泛型返回类型的虚拟函数? 我试图定义C++中的一个基类,该类具有由子类实现的纯虚方法。_C++_Oop - Fatal编程技术网

C++;:如何定义具有泛型返回类型的虚拟函数? 我试图定义C++中的一个基类,该类具有由子类实现的纯虚方法。

C++;:如何定义具有泛型返回类型的虚拟函数? 我试图定义C++中的一个基类,该类具有由子类实现的纯虚方法。,c++,oop,C++,Oop,我希望为基类中的基本类型定义setter和getter函数,但我希望派生类能够确定getter和setter的基本类型。例如,我的基类如下所示: class Value { public: Value(); template <class T>; virtual T getValue() = 0; virtual void setValue(T val) = 0; } class

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

    class Value
    {
    public:
        Value();
        template <class T>;
        virtual T getValue() = 0;
        virtual void setValue(T val) = 0;
    }
    class IntValue : public Value
    {
    public:
        IntValue();
        template <class T>
        T getValue() {return _val};
        void setValue(T val) {_val = val};
    private:
        int _val;
    }
类值
{
公众:
Value();
模板;
虚拟T getValue()=0;
虚空设置值(T val)=0;
}
我的孩子班看起来像这样:

    class Value
    {
    public:
        Value();
        template <class T>;
        virtual T getValue() = 0;
        virtual void setValue(T val) = 0;
    }
    class IntValue : public Value
    {
    public:
        IntValue();
        template <class T>
        T getValue() {return _val};
        void setValue(T val) {_val = val};
    private:
        int _val;
    }
class IntValue:公共值
{
公众:
IntValue();
模板
T getValue(){return};
void setValue(T val){u val=val};
私人:
国际价值;
}

当然,上面的代码不起作用。关于如何实现这一点有什么想法吗?提前感谢。

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

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;
};
模板
阶级价值
{
公众:
Value();
虚拟T getValue()=0;
虚空设置值(T val)=0;
};
类IntValue:公共值
{
公众:
IntValue();
int getValue(){return\u val;}
void setValue(int val){u val=val;}
私人:
国际价值;
};

应该有效

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

可以在中看到如何使用类模板(而不是函数模板)对基类进行此类修改的示例,但这仍然与问题描述不完全匹配,因为您无法创建
并对其进行多态性处理

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

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

扩展@Billy ONeal所说的关于类模板的内容,这可能适用于你的目的:

template<typename Type>
class Value
{
public:
    virtual Type getValue() = 0;
};

class IntValue : public Value<int>
{
public:
    IntValue(int value)
        : m_value(value)
    {
    }

    int getValue()
    {
        return m_value;
    }

private:
    int m_value;
};
模板
阶级价值
{
公众:
虚拟类型getValue()=0;
};
类IntValue:公共值
{
公众:
int值(int值)
:m_值(值)
{
}
int getValue()
{
返回m_值;
}
私人:
int m_值;
};

+1--这并不能回答OP的问题,但鉴于OP对类的命名和问题的描述,它可能会达到与OP真正想要的效果类似的效果。在这种情况下,
IntValue
不是
Value
的子类。因此,
virtual
关键字没有任何意义。你不能定义一个函数,它接受一个
值*
并向它传递一个
IntValue
。@Steven:的确;您甚至不能首先创建
值*
;对于某些类型,它必须是
值*
。因此,实际上这意味着我最好在子类中定义setter和getter,并将其从基类中删除。因为我必须使用
Value*
,但不能使用
Value*
,这会使事情变得复杂。这与J_D的解决方案有何不同?不同之处在于我没有看到他的解决方案(奇怪的是,我看到了你的)。但是,我做到了,投票支持他的解决方案。你已经撞上了
虚拟的
墙……如果类型数量有限,你可以使用boost的
变体
类型来实现有限数量的动态类型。@edA-qamort-ora-y:对于不受限制的类型集,你也可以使用
boost::any
,但你需要付出一定程度的间接性。I希望更多的人真正了解模板的真正含义。模板是具有类型检查和其他功能的宏。