Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.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++_Inheritance_Multiple Inheritance - Fatal编程技术网

C++ 我是否在一个特殊的案例中证明多重继承是合理的?

C++ 我是否在一个特殊的案例中证明多重继承是合理的?,c++,inheritance,multiple-inheritance,C++,Inheritance,Multiple Inheritance,目前,我有以下管理不同类型变量的类: class Variable; class Number : public Variable; class Boolean : public Variable; class RealNumber : public Number; class IntegerNumber : public Number; 这是一个经典的继承树,它工作得很好。我管理Number*实例的向量和Boolean*实例的向量 我想添加另一种类型的变量:具有特定行为但具有类似接口的“虚拟

目前,我有以下管理不同类型变量的类:

class Variable;
class Number : public Variable;
class Boolean : public Variable;
class RealNumber : public Number;
class IntegerNumber : public Number;
这是一个经典的继承树,它工作得很好。我管理
Number*
实例的向量和
Boolean*
实例的向量

我想添加另一种类型的变量:具有特定行为但具有类似接口的“虚拟变量”。然后,我想处理“虚拟数”向量和“虚拟布尔”向量

第一种解决方案是在
Variable
中添加一个标志,但我更喜欢编译安全性,并管理
std::vector
std::vector
,以保证变量在向量中是虚拟的

然后,我想也许我是在一个特殊的情况下,多重继承是合理的,但我是新的多重继承你觉得这类课程怎么样?

class VirtualVariable : public virtual Variable;
class VirtualNumber : public virtual Number, public virtual VirtualVariable;
class VirtualBoolean : public virtual Boolean, public virtual VirtualVariable;
class VirtualRealNumber : public virtual RealNumber, public virtual VirtualNumber;
class VirtualIntegerNumber : public virtual IntegerNumber, public virtual VirtualVariable;
这是一种经典的方式吗?这可能是个陷阱吗?我是否滥用了
virtual
关键字

编辑:我想做的示例:

void my_function(const std::vector<SpecItem>& spec)
{
  // First : create the description from the spec
  std::vector<Number*> descr;
  std::vector<VirtualNumber*> virt_descr;
  for(unsigned long int i = 0; i < spec.size(); ++i)
  {
    if(spec[i].isNumber())
      if(spec[i].isReal())
      {
        double lower_bound = spec[i].lowerBound();
        double upper_bound = spec[i].upperBound();
        if(spec[i].isVirtual())
        {
          std::string formula = spec[i].formula();
          virt_descr.push_back(new VirtualRealNumber(lower_bound,upper_bound,formula));
        }
        else
          descr.push_back(new RealNumber(lower_bound,upper_bound));
      }
      else if(spec[i].isInteger())
      {
        long int lower_bound = ceil(spec[i].lowerBound());
        long int upper_bound = floor(spec[i].upperBound());
        if(spec[i].isVirtual())
        {
          std::string formula = spec[i].formula();
          virt_descr.push_back(new VirtualIntegerNumber(lower_bound,upper_bound,formula));
        }
        else
          descr.push_back(new IntegerNumber(lower_bound,upper_bound));
      }
  }
  // Now, descr is a vector of Number*, virt_descr is a vector of VirtualNumber*

  // Second step : assign values to the numbers
  std::vector<double> values;
  for(unsigned long int i = 0; i < descr.size(); ++i)
  {
    double new_value = (descr[i]->lowerBound() + descr[i]->upperBound()) / 2.0;
    values.push_back(descr[i]->adjust(new_value));
  }

  // Third step : evaluate virtual numbers
  std::vector<double> virt_values;
  for(unsigned long int i = 0; i < virt_descr.size(); ++i)
  {
    double new_value = virt_descr[i]->evaluate(values);
    values.push_back(descr[i]->adjust(new_value));
  }

  return 0;
}
void my_函数(const std::vector&spec)
{
//第一:从等级库创建描述
std::矢量描述;
std::载体病毒描述;
for(无符号长整数i=0;ilowerBound()+descr[i]>upperBound())/2.0;
值。推回(描述[i]->调整(新值));
}
//第三步:评估虚拟数字
std::向量virt_值;
for(无符号长整数i=0;i评估(值);
值。推回(描述[i]->调整(新值));
}
返回0;
}

我尽量避免多重继承。 听起来你想要一个类似于基本对象的对象,但在特定情况下会有所改变。听起来像是一个类规范。我不确定你的目标是什么,但也许你可以把你的设计改成一个经典的层次模型。为了实现这一点,将所有特定代码放在单独的函数中,然后在基类中调用

class Number : public Variable
{
    ...
    protected:
        virtual void functionWithSpecialUsage() { // Empty in base class, used by inheritance only };
}

class VirtualNumber : public Number
{
    ...
    protected:
        void functionWithSpecialUsage() { // Add class specific behavior here };
}

多重继承意味着通过确保安全性来支持干净的设计。因此,这是完全合理的

如果不了解更多的原因和约束条件,就很难对最佳的类设计提出建议。但有些问题可能会对你有所帮助

它从以下行开始:

    class VirtualVariable : public virtual Variable;
1)您需要虚拟继承吗?

class VirtualVariable : public virtual Variable;
class VirtualNumber : public virtual Number, public virtual VirtualVariable;
class VirtualBoolean : public virtual Boolean, public virtual VirtualVariable;
class VirtualRealNumber : public virtual RealNumber, public virtual VirtualNumber;
class VirtualIntegerNumber : public virtual IntegerNumber, public virtual VirtualVariable;
多重继承在虚拟继承之前是非常简单和有趣的。这意味着对于从
VirtualVariable
多次继承的类,所有
VirtualVariable
子对象实例将共享一个
变量
基对象。有关更多信息,请阅读

在您的设计中,您可能需要为
变量
的每个继承(包括非“虚拟”继承)使用它,以避免有多个
变量
子对象,而实际上只有一个子对象。你不应该把它用于其他继承

这个虚拟继承将要求,对于每个构造函数,您显式地初始化您的虚拟基

2)变量
和虚拟变量
之间的真正关系是什么?

class VirtualVariable : public virtual Variable;
class VirtualNumber : public virtual Number, public virtual VirtualVariable;
class VirtualBoolean : public virtual Boolean, public virtual VirtualVariable;
class VirtualRealNumber : public virtual RealNumber, public virtual VirtualNumber;
class VirtualIntegerNumber : public virtual IntegerNumber, public virtual VirtualVariable;
根据你的解释,我理解“虚拟性”概念独立于“变量”概念。另一方面,在代码中,您假装
虚拟变量
是一个
变量

如果它是独立的,你应该保持它的独立性。这将更好地分离关注点。好消息是,您不再需要虚拟继承:

class Virtuality;     
class VirtualVariable : public Variable, public Virtuality;
class VirtualNumber : public Number, public Virtuality;
class VirtualBoolean : public Boolean, public Virtuality;
class VirtualRealNumber : public RealNumber, public Virtuality;
class VirtualIntegerNumber : public IntegerNumber, public Virtuality;
3)您看过模板了吗?

class VirtualVariable : public virtual Variable;
class VirtualNumber : public virtual Number, public virtual VirtualVariable;
class VirtualBoolean : public virtual Boolean, public virtual VirtualVariable;
class VirtualRealNumber : public virtual RealNumber, public virtual VirtualNumber;
class VirtualIntegerNumber : public virtual IntegerNumber, public virtual VirtualVariable;
你说:

第一种解决方案是在变量中添加一个标志,但我更喜欢 编译安全与管理

如果仅用于编译类型检查,则可以使用模板:

template <bool isvirtual>
Variable { ...};
template <bool isvirtual>
class Number :  Variable<isvirtual> { ...};
...
std::vector<Number<true>*> v; 

*顺便说一下,我认为结构
if(isxxx())。。。如果代码中的(isyyy())…
强烈建议您使用多态性

我建议您看看这一点(在下面,您可以提供一个示例来演示上述指导原则吗?),看看是否有任何替代方案适合您。我的意见是,如果不首先理解目标,继承(多重或其他、虚拟或其他)就无法正确设计。编写继承或面向对象设计不能成为目标。那么这里的目标是什么?你想实现什么?管理
std::vector
std::vector
对象的方法与我目前使用的
std::vector
算法相同<代码>虚拟变量
在求值时仅具有特定行为,但保留