这个赋值运算符可以吗,复制ctor可以吗? [英] is this assignment operator ok and copy ctor ok

查看:135
本文介绍了这个赋值运算符可以吗,复制ctor可以吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道这个赋值运算符和复制构造函数是否正常.我刚开始上课.在删除后将指针设置为NULL也是一种好习惯还是毫无意义.

#include <iostream>
#include <string>

using std::cout;
using std::endl;
using std::cin;

class stickfigure
{
public:
    stickfigure(int j)
    : test(new int(j))
    {}
    stickfigure(const stickfigure& ref)
    : test(new int(*ref.test))
    {}
    stickfigure& operator = (const stickfigure& ref)
    {
        if (this != &ref)
        {
            delete test;
            test = new int(*ref.test);
        }
        return *this;
    }
    virtual ~stickfigure(){ delete test;}
    void print() const{cout << *test << endl;}
private:
    int* test;
};

int main(int argc, char** argv)
{
    stickfigure stickone(76);
    stickone.print();
    // copy
    stickfigure sticktwo(stickone);
    sticktwo.print();
    // assignment
    stickfigure stickthree = sticktwo;
    stickthree.print();
}

解决方案

对我来说很好.由于您在析构函数中删除了test,因此将其设置为NULL 不会有任何影响.人们通常会这样做,只要变量可以在对象的生存期内任意地delete''d/new''d,在这种情况下,最好能够检查字段的有效性,因此有些人们确实在delete -ing之后将其设置为NULL .


OT改进:
代替stickfigure::print,放入stickfigure声明

 朋友 std :: ostream&运算符<(std :: ostream& s, const  stickfigure& z)
{
    返回 s<< * z.test;
} 


这样,在main中,您可以执行

cout << stickone << endl << sticktwo << endl << stickthree << endl;


如果将cout 替换为任何文件流,这也将起作用.赋值运算符不是异常安全或中立的.如果赋值运算符中的new引发,则您的对象处于不确定状态.

如果使用复制和交换惯用语,则将同时获得异常安全性和中立性,并且使赋值运算符长三行,而不会遇到任何逻辑上的障碍:

stickfigure& operator = (const stickfigure& ref)
{
    stickfigure temp( ref );
    std::swap( ref.test, test );
    return *this;
}



这是一个非常值得了解的习惯用法,在Herb Sutter的"Exception C ++"中有很好的描述.当您阅读入门教材时,非常值得一读.

干杯,


I was wondering if this assignment operator and copy constructor looks ok. I am just starting classes. also would it be good practice or pointless to set the pointer to NULL after delete.

#include <iostream>
#include <string>

using std::cout;
using std::endl;
using std::cin;

class stickfigure
{
public:
    stickfigure(int j)
    : test(new int(j))
    {}
    stickfigure(const stickfigure& ref)
    : test(new int(*ref.test))
    {}
    stickfigure& operator = (const stickfigure& ref)
    {
        if (this != &ref)
        {
            delete test;
            test = new int(*ref.test);
        }
        return *this;
    }
    virtual ~stickfigure(){ delete test;}
    void print() const{cout << *test << endl;}
private:
    int* test;
};

int main(int argc, char** argv)
{
    stickfigure stickone(76);
    stickone.print();
    // copy
    stickfigure sticktwo(stickone);
    sticktwo.print();
    // assignment
    stickfigure stickthree = sticktwo;
    stickthree.print();
}

解决方案

Looks good to me. Since you delete test in the destructor, setting it to NULL won''t affect anything. People normally do that when the variable can be delete''d/new''d arbitrarily within the lifetime of the object, in that case it''s good to be able to check the field for validity and so some people do set it to NULL after delete-ing it.


An OT emprovement:
instead of stickfigure::print, into stickfigure declare

friend std::ostream& operator<<(std::ostream& s, const stickfigure& z)
{
    return s << *z.test;
}


so that, in main, you can do

cout << stickone << endl << sticktwo << endl << stickthree << endl;


This will work also if cout will be replaced with whatever file stream.


Your copy constructor looks fine (ignoring the whole "why store an int as a dynamic object" thing) but your assignment operator is not exception safe or neutral. If the new in the assignment operator throws then your object is in an indeterminate state.

If you use the copy and swap idiom you get both exception safety and neutrality AND scarily make the assignment operator three lines long without any logic getting in the way:

stickfigure& operator = (const stickfigure& ref)
{
    stickfigure temp( ref );
    std::swap( ref.test, test );
    return *this;
}



It''s an idiom well worth knowing and is pretty well described in "Exception C++" by Herb Sutter. When you get through your introductory text book it''s well worth a read.

Cheers,

Ash


这篇关于这个赋值运算符可以吗,复制ctor可以吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆