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_Inheritance_Abstract Class_Instantiation - Fatal编程技术网

C++ 在c+中创建派生抽象类的实例+;

C++ 在c+中创建派生抽象类的实例+;,c++,oop,inheritance,abstract-class,instantiation,C++,Oop,Inheritance,Abstract Class,Instantiation,我遇到了这个问题,不知道如何解决它 假设我有这些基类: class ValueBase { private: int base_value; public: int GetValue(); void SetValue(int val); virtual ValueBase* Meet(ValueBase* const a, ValueBase* const b) = 0; } class NodeBase { private:

我遇到了这个问题,不知道如何解决它

假设我有这些基类:

class ValueBase
{
    private:
    int base_value;

    public:
    int GetValue();
    void SetValue(int val);
    virtual ValueBase* Meet(ValueBase* const a, ValueBase* const b) = 0;
}

class NodeBase
{
    private:
    ValueBase* base_nodeValue;

    public:
    bool AddValue(int val);
}
和派生类:

class Value : public ValueBase
{
    public:
    Value* Meet(ValueBase* a, ValueBase* b) override;
}
是否有一种方法可以在class
NodeBase
中的方法
AddValue
中创建class
Value
的实例?我知道我可能应该将
AddValue
设置为纯虚拟,并在
NodeBase
的派生类中实现它,但是没有这个选项是否有可能实现它?例如,我可以使用template方法,或者可能是对
Value
中的方法的回调来构造该对象吗?还是做这件事太邪恶了

编辑:
在类
节点库中,我没有访问派生类
值的权限添加创建成员函数:

class ValueBase
{
public:
    virtual ValueBase * create() = 0;
    // ...
};
然后在
NodeBase
中,可以使用
base\u nodeValue->create()

派生类实现它:

class Value : public ValueBase
{
    Value * create() override { return new Value; }
};
不过,此模式更常见的形式是克隆函数,它不生成相同类型的默认构造对象,而是生成一个副本:


添加创建成员函数:

class ValueBase
{
public:
    virtual ValueBase * create() = 0;
    // ...
};
然后在
NodeBase
中,可以使用
base\u nodeValue->create()

派生类实现它:

class Value : public ValueBase
{
    Value * create() override { return new Value; }
};
不过,此模式更常见的形式是克隆函数,它不生成相同类型的默认构造对象,而是生成一个副本:


我看不到不改变类定义的方法。但是,有许多方法涉及更改类定义,具体取决于“允许”使用的内容

A.将
AddValue()
模板化到它应该创建的对象类型上:

 class NodeBase
 {
    private:
    ValueBase* base_nodeValue;

    public:
    template<class ValueType>
    bool AddValue(int val) { base_nodeValue = new ValueType; }
 }

 ...
 // other code that has access to Value
 node.AddValue<Value>(10);
(此处也可以使用函子或lambda)

C.您可以在
ValueBase
中创建一个返回
Value*
的函数

class ValueBase
{
    public:
    static ValueBase* createValue();
};

class NodeBase
{
    private:
    ValueBase* base_nodeValue;

    public:
    bool AddValue(int val) { base_nodeValue = ValueBase::createValue(); }
};

// in a separate cpp
ValueBase* ValueBase::createValue() { return new Value; }

这实际上类似于工厂方法:您可以让
createValue()
接受一个参数,并根据它创建不同的
ValueBase
s。让
ValueBase
存储一些指向creator函数的指针,您可以让它根本不知道
Value
,只需在其他位置初始化该指针,就像您可以在基类的工厂表中注册子类一样。

我看不到不更改类定义的方法。但是,有许多方法涉及更改类定义,具体取决于“允许”使用的内容

A.将
AddValue()
模板化到它应该创建的对象类型上:

 class NodeBase
 {
    private:
    ValueBase* base_nodeValue;

    public:
    template<class ValueType>
    bool AddValue(int val) { base_nodeValue = new ValueType; }
 }

 ...
 // other code that has access to Value
 node.AddValue<Value>(10);
(此处也可以使用函子或lambda)

C.您可以在
ValueBase
中创建一个返回
Value*
的函数

class ValueBase
{
    public:
    static ValueBase* createValue();
};

class NodeBase
{
    private:
    ValueBase* base_nodeValue;

    public:
    bool AddValue(int val) { base_nodeValue = ValueBase::createValue(); }
};

// in a separate cpp
ValueBase* ValueBase::createValue() { return new Value; }

这实际上类似于工厂方法:您可以让
createValue()
接受一个参数,并根据它创建不同的
ValueBase
s。让
ValueBase
存储一些指向creator函数的指针,您可以让它根本不知道
Value
,只需在其他地方初始化该指针,就像您可以在基类的工厂表中注册子类一样。

bool AddValue(int val){base\u nodeValue=new Value;}
boom,完成了,我遗漏了一个要点,请参见编辑。你不能向前声明
,或者包含正确的标题以便在
节点库
中使用它吗?@JonathanPotter将此作为答案,以便它可以被接受问题的标题是错误的和误导的,它表明你想要创建一个抽象类的实例,这当然是不可能的。事实上,你想创建一个从抽象类派生的类的实例是不相关的,你可以说“创建派生类的实例”,因为这就是你要做的,它与基是否是抽象的没有区别。
bool AddValue(int val){base_nodeValue=new Value;}
boom,done,我遗漏了一个要点,请参见编辑。你不能向前声明
,或者包含正确的标题以便在
节点库
中使用它吗?@JonathanPotter将此作为答案,以便它可以被接受问题的标题是错误的和误导的,它表明你想要创建一个抽象类的实例,这当然是不可能的。事实上,您想要创建一个从抽象类派生的类的实例是不相关的,您可以说“创建派生类的实例”,因为这就是您要做的,它与基是否抽象没有关系。这解决不了任何问题。使用这种方法,您需要具有正确派生类型的对象才能创建具有正确派生类型的对象。OP显然想创建一个,但还没有。@KerrekSB,它可能是空的,或者其他的,正如我读的question@JSF,我认为“显然”情况并非如此。OP说“可能是对
Value
中的方法的回调”,这非常强烈地表明有一个对象来调用该方法是一个有效的考虑因素。这并不能解决任何问题。使用这种方法,您需要具有正确派生类型的对象才能创建具有正确派生类型的对象。OP显然想创建一个,但还没有。@KerrekSB,它可能是空的,或者其他的,正如我读的question@JSF,我认为“显然”情况并非如此。OP说“可能是对
Value
中的方法的回调”,这非常强烈地表明,有一个对象来调用该方法是一个有效的考虑因素。谢谢,对我来说,这是一个非常好的答案:)我最终使用了模板方法,使用了一些
静态断言
,效果非常好谢谢,对我来说,这是一个非常好的答案:)我最终使用了模板方法,使用了一些
static\u assert
,效果非常好