3

许多类的赋值运算符(operator=)与析构函数中的代码相同,并且与复制构造函数的代码非常相似。

那么以这种方式实施分配是个好主意吗?

Point& operator=(const Point& point)
{
    if(&point != this)
    {
        //Call the destructor
        this->~Point();

        //Make the placement new
        //Assignment is made because some compilers optimise such code as just
        //  new Point;
        Point* p_n = new (this) Point(point);

        //We where placing in this place so pointers should be equal
        assert(p_n == this);
    }
    return *this;
}
4

2 回答 2

6

不,这是一个坏主意,尽管 C++ 标准在讨论对象生命周期时使用了这种东西作为示例。对于像Point它这样的值类型还不错,但是如果您从此类派生,则此赋值实现会将对象的类型从您的派生类型更改为Point; 如果涉及到虚函数,您会看到行为的巨大变化。

于 2013-04-10T17:20:38.593 回答
3

Herb Sutter在他的一篇 GotW 文章中谈到了这一点。我建议你阅读它。他的结论:

最初的习语充满了陷阱,经常出错,它使派生类的作者的生活变成了地狱。我有时很想在办公室厨房张贴上面的代码,并附上标题:“这里有龙。”

来自 GotW 编码标准:

  • 如有必要,更喜欢编写一个通用的私有函数来在复制和复制分配之间共享代码;永远不要使用在复制构造方面通过使用显式析构函数然后放置 new 来实现复制分配的技巧,即使这个技巧每三个月在新闻组上出现一次(即,永远不要写:

    T& T::operator=( const T& other )
    {
        if( this != &other)
        {
            this->~T();             // evil
            new (this) T( other );  // evil
        }
        return *this;
    }
    
于 2013-04-10T17:38:15.857 回答