0

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

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

编辑:

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

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;
}
4

2 回答 2

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();

于 2012-07-04T19:26:03.560 回答
0
  1. 克隆不应该有参数,因为它应该克隆自己。如果你想改变 *this 你有 operator =。
  2. 尝试返回值。如果您作为回报创建临时对象,则编译器可以对其进行优化以在没有临时对象的情况下构造新对象。

    AnimatedSprite AnimatedSprite::Clone() { return AnimatedSprite(*this); }

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

// 已编辑

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

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

AnimatedSprite& AnimatedSprite::CopyFrom(AnimatedSprite& animatedSprite) {
    return (*this = animatedSprite);
}
于 2012-07-04T19:32:58.857 回答