在 C++ 中创建派生抽象 class 的实例
Create instance of derived abstract class in c++
我遇到了这个问题,不知道怎么解决。
假设我有这些基础 classes:
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:
class Value : public ValueBase
{
public:
Value* Meet(ValueBase* a, ValueBase* b) override;
}
有没有办法在 class NodeBase
的方法 AddValue
中创建 class Value
的实例?我知道我应该使 AddValue
纯虚拟并在 NodeBase
的派生 class 中实现它,但是如果没有这个选项是否有可能做到这一点?我可以使用例如模板方法或者可能是 Value
中构造该对象的方法的回调?还是这样做太邪恶了?
已编辑:
我无法访问 class NodeBase
中的派生 class Value
添加创建成员函数:
class ValueBase
{
public:
virtual ValueBase * create() = 0;
// ...
};
然后在NodeBase
中你可以使用base_nodeValue->create()
.
派生类实现它:
class Value : public ValueBase
{
Value * create() override { return new Value; }
};
此模式更常见的形式是 clone 函数,但它不会生成相同类型的默认构造对象,而是 复制:
Derived * clone() override { return new Derived(*this); }
我看不到不改变 class 定义的方法。但是,有许多方法涉及更改 class 定义,具体取决于您 "allowed" 要使用的内容。
一个。将 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);
乙。创建创建 Value
的函数(如果需要,将任何参数转发给构造函数) and pass it as an argument to
AddValue`:
// might need to adapt syntax
class NodeBase
{
private:
ValueBase* base_nodeValue;
public:
bool AddValue(int val, ValueBase* (*creator)()) { base_nodeValue = (*creator)(); }
}
...
// other code that has access to Value
ValueBase* valueCreator() { return new Value; }
...
node.AddValue(10, valueCreator);
(这里也可以使用仿函数或 lambda)
摄氏度。您可以在 ValueBase
中创建一个 returns 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
。让 ValueBase
存储一些指向 creator 函数的指针,你可以让它根本不知道 Value
,只需在其他地方初始化该指针,就像你可以在 a 中注册一个 subclass基地 class.
中的工厂 table
我遇到了这个问题,不知道怎么解决。
假设我有这些基础 classes:
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:
class Value : public ValueBase
{
public:
Value* Meet(ValueBase* a, ValueBase* b) override;
}
有没有办法在 class NodeBase
的方法 AddValue
中创建 class Value
的实例?我知道我应该使 AddValue
纯虚拟并在 NodeBase
的派生 class 中实现它,但是如果没有这个选项是否有可能做到这一点?我可以使用例如模板方法或者可能是 Value
中构造该对象的方法的回调?还是这样做太邪恶了?
已编辑:
我无法访问 class NodeBase
Value
添加创建成员函数:
class ValueBase
{
public:
virtual ValueBase * create() = 0;
// ...
};
然后在NodeBase
中你可以使用base_nodeValue->create()
.
派生类实现它:
class Value : public ValueBase
{
Value * create() override { return new Value; }
};
此模式更常见的形式是 clone 函数,但它不会生成相同类型的默认构造对象,而是 复制:
Derived * clone() override { return new Derived(*this); }
我看不到不改变 class 定义的方法。但是,有许多方法涉及更改 class 定义,具体取决于您 "allowed" 要使用的内容。
一个。将 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);
乙。创建创建 Value
的函数(如果需要,将任何参数转发给构造函数) and pass it as an argument to
AddValue`:
// might need to adapt syntax
class NodeBase
{
private:
ValueBase* base_nodeValue;
public:
bool AddValue(int val, ValueBase* (*creator)()) { base_nodeValue = (*creator)(); }
}
...
// other code that has access to Value
ValueBase* valueCreator() { return new Value; }
...
node.AddValue(10, valueCreator);
(这里也可以使用仿函数或 lambda)
摄氏度。您可以在 ValueBase
中创建一个 returns 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
。让 ValueBase
存储一些指向 creator 函数的指针,你可以让它根本不知道 Value
,只需在其他地方初始化该指针,就像你可以在 a 中注册一个 subclass基地 class.