gpt4 book ai didi

c++ - 从基类指针访问派生类成员的设计替代方案

转载 作者:行者123 更新时间:2023-11-28 07:05:16 25 4
gpt4 key购买 nike

我正在编写一个 DAL/ORM 库。这个库将主要从 GUI 访问,但也可以从一些“业务级”应用程序访问。我仍处于该库的设计阶段,并不确定如何很好地解决以下问题。

在我目前的设计中,我有一个类,我们暂时称它为 List,它有另一个类 Properties 的容器。属性有两种类型(A 和 B),功能基本相同,但有些功能不同。此外,两种类型的 Properties 都存储值。值可以是不同的数据类型,包括但不限于 POD。每个 List 只能包含某个 Property 一次,并且 Properties 由“名称”(即字符串)标识。

我现在希望能够执行以下所有操作:

  • 尽可能降低界面的复杂度
  • 遍历 List 中的所有 Properties,并调用 Property 风格都支持的方法。
  • 当拥有 Property 实例时,以类型安全的方式访问它的值
  • 如果可能,避免使用dynamic_cast 或类似的结构

所以,显然纯粹的多态性不能解决这个问题。我用奇怪地重复出现的模板模式和两个类层次结构的组合做了一些实验——一个用于Properties,一个用于它们的值(示例下面的代码)。然而,到目前为止,我还没有成功获得满足我所有要求的设计。

基本设计(即存在哪些类,它们是如何组织的等)不是固定的,可以很容易地改变。我还处于这个项目的设计阶段,所以只有测试代码存在。但是,基本思想必须像上面解释的那样(即 List 具有 Properties,后者又具有 values)。

对我的问题或原始想法、想法等的任何解决方案都非常感谢。


层次结构实现的示例代码。显然,在这里我无法以类型安全的方式访问属性的值。

class PropertyValue {
public:
virtual std::string GetAsString() const = 0;

bool IsReadOnly() const { return m_isReadOnly; }
void IsReadOnly(const bool val) { m_isReadOnly = val; }

protected:
PropertyValue(PropertyValue & other) : m_isReadOnly(other.m_isReadOnly)
{};

PropertyValue(bool readOnly) : m_isReadOnly(readOnly)
{};

private:
bool m_isReadOnly;
};

class StringValue : public PropertyValue {
private:
typedef std::string inner_type;
public:
StringValue(const inner_type & value, bool readOnly) : PropertyValue(readOnly)
, m_value(value)
{};

StringValue(StringValue & other) : PropertyValue(other.IsReadOnly())
, m_value(other.m_value)
{};

std::string GetAsString() const { return m_value; };

inner_type GetValue() const { return m_value; };
void SetValue(const inner_type & value) { m_value = value; };

unsigned int GetMaxLenght() const { return m_maxLength; };

private:
inner_type m_value;
unsigned int m_maxLength;
};

class IntValue : public PropertyValue {
private:
typedef int inner_type;
public:
IntValue(const inner_type & value, bool readOnly) : PropertyValue(readOnly)
, m_value(value)
{};

IntValue(IntValue & other) : PropertyValue(other.IsReadOnly())
, m_value(other.m_value)
{};

std::string GetAsString() const { char tmp[((CHAR_BIT * sizeof(int)) / 3 + 1)]; return itoa(m_value, tmp, 10); };

inner_type GetValue() const { return m_value; };
void SetValue(const inner_type & value) { m_value = value; };

int GetMinValue() const { return m_minValue; };
int GetMaxValue() const { return m_maxValue; };

private:
inner_type m_value;
int m_minValue;
int m_maxValue;
};

class Property {
public:
Property(std::auto_ptr<PropertyValue> value, bool visible)
{
m_value = value;
m_isVisible = visible;
}

bool IsVisible() const { return m_isVisible; }
void IsVisible(const bool val) { m_isVisible = val; }

std::string GetValueAsString() const { return m_value->GetAsString(); };

const PropertyValue & getValue() const { return (*m_value.get()); }

private:
std::auto_ptr<PropertyValue> m_value;
bool m_isVisible;
};

class PropertyFlavorA : public Property {
public:
PropertyFlavorA(std::auto_ptr<PropertyValue> value, bool visible) : Property(value, visible)
{
value->IsReadOnly(true);
};
};

class PropertyFlavorB : public Property {
public:
PropertyFlavorB(std::auto_ptr<PropertyValue> value, bool visible) : Property(value, visible) {};
};

最佳答案

你似乎已经回答了你自己的问题......

Iterate over all Properties in List, and call methods that both Property flavors support.

这是 polymorphism .

Properties 的两种风格都有一个基类,它有一个虚函数,您的 A 和 B Property 类会覆盖它。然后,您可以从存储在 List 中的基类指针调用该函数。

关于c++ - 从基类指针访问派生类成员的设计替代方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21859424/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com