【问题标题】:C++ - Change the type of an objectC++ - 更改对象的类型
【发布时间】:2016-04-15 04:41:27
【问题描述】:

简而言之:

对象一旦建立就可以改变类型吗?

我的尝试:

例如给定设计: (编辑:澄清一下,这是一个策略设计模式的简化示例,ChangeData 的作用并不重要,我们可以通过更改 _interface 来改变它的作用)

struct MyClass
{
    int _data;
    MyInterface* _interface;

    void DoChangeData() { Interface->ChangeData(*this); }
};

MyClass x;
x._interface = new DerivedClass1();
x.DoChangeData(); // do something
x._interface = new DerivedClass2();
x.DoChangeData(); // do something else

切换_interface 允许我们更改对类的操作,但是这需要创建包装方法(DoChangeData)并始终将this 指针作为参数传递,这很难看。

我更喜欢的更好的解决方案是:

struct MyClass abstract
{
    int _data;

    virtual void ChangeData() = 0;
};

但是这里的具体类一旦建立,不像_interface,就不能改变了。如果不同的派生类不添加任何新字段,这似乎应该是可能的。有没有办法实现下面的ChangeClass函数?

DerivedClass1 x;
x.DoChangeData(); // do something
x.ChangeClass(DerivedClass2); // ???
x.DoChangeData(); // do something else

注意我说的是虚拟类,reinterpret_cast 只适用于非虚拟对象。复制构造函数需要移动现有内存的开销,我也宁愿避免。

【问题讨论】:

标签: c++ class inheritance overriding


【解决方案1】:

如果您解释实际问题而不是如何实施您的解决方案,这看起来可以得到更好的回答。

我不清楚DoChangeData 应该做什么以及为什么它需要引用MyClass。 问题陈述不够清楚,无法得到答案,并且标题(如所述)会得到 no 作为答案(在 C++ 中,您不能更改类型,是一种强类型语言),但是我明白这不是你要问的。

请澄清问题以获得满意的答案。

顺便说一句,您可能想看看Visitor design pattern 和/或Strategy design pattern

【讨论】:

  • 策略模式不就是例子中展示的吗?我会补充一些说明,谢谢。
  • 是的。抱歉没有仔细检查代码。很高兴将名称留作参考 ;-)
  • 我在您的编辑中说“...... ChangeData 的作用并不重要,我们可以通过更改 _interface 来改变它的作用”。因为changeData 需要访问容器对象(至少在示例中),我确实认为意图是什么很重要(这就是我最初要求澄清的原因,我想你可能会面临以另一种方式设计)。如果您需要改变MyClass 的处理方式,您可能需要反转“依赖关系”并使用访问者设计模式之类的东西。
【解决方案2】:

您可以在MyClass 中声明函数指针并更改它们以更改类型。或者使用指向函数指针数组的(const 指针)创建自己的 vtable,只需更改此指针即可更改类型。

【讨论】:

  • 所有这些都是正确的,但恕我直言,并不比已经实施的替代方案更好。当您没有多态性时(例如,如果使用 C),而不是在 C++ 中,这些是要使用的“hacks”。这就是为什么我认为需要更多细节才能真正帮助 OP。
猜你喜欢
  • 1970-01-01
  • 2019-10-30
  • 2015-03-20
  • 1970-01-01
  • 2018-04-09
  • 1970-01-01
  • 1970-01-01
  • 2014-05-31
  • 2013-07-04
相关资源
最近更新 更多