使用公共命名方法实现非公共赋值运算符?

时间:2012-07-04 19:20:34

标签: c++ clone assignment-operator

它应该复制一个AnimatedSprite。我有第二个想法,它有改变*这个对象的不幸副作用。

如何在没有副作用的情况下实现此功能?

编辑:

基于新的答案,问题应该是:如何使用公共命名方法实现非公共赋值运算符而没有副作用? (改变标题)。

public:
AnimatedSprite& AnimatedSprite::Clone(const AnimatedSprite& animatedSprite) {
    return (*this = animatedSprite);
}

protected:
AnimatedSprite& AnimatedSprite::operator=(const AnimatedSprite& rhs) {
    if(this == &rhs) return *this;

    destroy_bitmap(this->_frameImage);
    this->_frameImage = create_bitmap(rhs._frameImage->w, rhs._frameImage->h);
    clear_bitmap(this->_frameImage);
    this->_frameDimensions = rhs._frameDimensions;
    this->CalcCenterFrame();
    this->_frameRate = rhs._frameRate;
    if(rhs._animation != nullptr) {
        delete this->_animation;
        this->_animation = new a2de::AnimationHandler(*rhs._animation);
    } else {
        delete this->_animation;
        this->_animation = nullptr;
    }

    return *this;
}

2 个答案:

答案 0 :(得分:1)

您可以调用私有赋值运算符:

public:
AnimatedSprite& AnimatedSprite::Clone(const AnimatedSprite& animatedSprite) {
    return ( operator=(animatedSprite));
}

如果您正在尝试执行作业,则无法修改this

<击> 通常,clone会返回指向新实例的指针或智能指针:

struct IFoo {
  virtual IFoo* clone() const = 0;
};
struct Foo1 : public virtual IFoo {
  virtual IFoo* clone() { return new Foo1(this);}
};
struct Foo2 : public virtual IFoo {
  virtual IFoo* clone() { return new Foo2(this);}
};

IFoo* foo0 = new Foo1();
...
IFoo* fooClone = foo0.clone();

<击>

答案 1 :(得分:0)

  1. 克隆不应该有参数,因为它应该克隆自己。如果你想改变*这个你有operator =。
  2. 尝试返回值。如果你创建了temp对象,那么可以通过编译器优化它来构造没有temp的新对象。

    AnimatedSprite AnimatedSprite :: Clone(){     返回AnimatedSprite(* this); }

    AnimatedSprite clone = someObject.Clone(); //不会导致创建临时对象

  3. //编辑

    所以你需要这样的东西?另外我不确定,为什么你需要参考返回。

    public:
    AnimatedSprite& AnimatedSprite::CopyTo(AnimatedSprite& animatedSprite) {
        animatedSprite = *this;
        return *this;
    }
    
    AnimatedSprite& AnimatedSprite::CopyFrom(AnimatedSprite& animatedSprite) {
        return (*this = animatedSprite);
    }