Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.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++_Clone_Virtual_Member_Non Virtual Interface - Fatal编程技术网

C++ 具有非虚拟接口和一些私有变量的克隆方法

C++ 具有非虚拟接口和一些私有变量的克隆方法,c++,clone,virtual,member,non-virtual-interface,C++,Clone,Virtual,Member,Non Virtual Interface,我有一个抽象类,比如说Figure,还有一些派生类:Circle,Square 类图实现了: private: virtual double varea()=0; double multiplier; public: virtual Figure * clone()=0; double area() { return varea()*multiplier; } 例如,正方形图形的行为如下: private: double L; public: virtual Figur

我有一个抽象类,比如说
Figure
,还有一些派生类:
Circle
Square

类图实现了:

private:
  virtual double varea()=0;
  double multiplier;
public:
  virtual Figure * clone()=0;
  double area() { return varea()*multiplier; }
例如,正方形图形的行为如下:

private:
  double L;
public:
  virtual Figure * clone() {return new Square(*this);}
  virtual double varea() {return L*L;}
调用clone方法时,我很难分配变量乘数。实现这一目标的最佳方式是什么?当然,这只是一个愚蠢的例子,有很多变通方法,但实际上,有多个派生级别,它们并不那么明显,所以请坚持这种模式



我是否也应该为方法克隆选择虚拟接口?通过这种方式,我可以直接在Figure类中分配乘数,而无需让每个Figure知道其乘数。

向Figure类添加受保护的访问器:

protected:
  double getMultiplier() { return multiplier; }
  void setMultiplier(double newValue) { multiplier = newValue; }

这样,您就可以访问乘法器,尽管您无法直接访问该成员。

除非您为类声明了一个副本构造函数。该语言免费为您提供一个,并且是公共的。您不需要这个免费的公共副本构造函数。这将导致切片。使类的复制构造函数受保护。非抽象派生类的复制构造函数应调用此受保护的复制构造函数。这样,克隆成员函数就简单得像
new-DerivedClass(*this)

请注意:

  • 我将
    Square::varea()
    设为私有,因为它在类
    图中是这样声明的。在派生类中将父类的私有方法公开为公共方法通常有点可疑
  • 赋值运算符有问题。这件事由你决定
  • 您需要某种方法来设置
    乘数

    • 继承与复制语义笨拙地连接。但是,一种解决方案是让复制构造函数执行此任务:

      struct Base
      {
      public:
          Base()=default;
          virtual ~Base()=default;
      
          virtual Base* clone()=0;
      
          Base& operator=(Base const &) = delete;
          Base(Base&&)=delete;
      protected:
          Base(Base const&) = default;
      };
      
      struct Derivated : Base
      {
      public:
          Derivated()=default;
      
          virtual Derivated * clone()
          {
              return new Derivated (*this);
          }
      protected:
          Derivated(Derivated const&) = default;
      };
      

      乘数是私有的,所以您要么需要一个受保护的setter,要么需要一个将乘数作为参数的构造函数。然后子类构造函数可以将乘数值传递给父构造函数。@我希望能够避免编辑所有现有的派生图形,并为我仍然需要编写的图形保留轻型构造函数。没有其他理由让数字看到它们的乘数。我不清楚如何通过这样做来解决问题。在派生的类中,clone方法返回的
      派生的*
      只是一个输入错误吗?我不太熟悉默认的复制构造函数,它是
      派生的(派生常量&)=default同时调用
      Base(Base const&)
      ?1)谢谢,我的不精确!2) 是的,它必须使用克隆方法。3) 当然!
      struct Base
      {
      public:
          Base()=default;
          virtual ~Base()=default;
      
          virtual Base* clone()=0;
      
          Base& operator=(Base const &) = delete;
          Base(Base&&)=delete;
      protected:
          Base(Base const&) = default;
      };
      
      struct Derivated : Base
      {
      public:
          Derivated()=default;
      
          virtual Derivated * clone()
          {
              return new Derivated (*this);
          }
      protected:
          Derivated(Derivated const&) = default;
      };