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;
}
是否有一种方法可以在classNodeBase
中的方法AddValue
中创建classValue
的实例?我知道我可能应该将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
,效果非常好