我读了somewhere:
每个具有指针数据成员的类都应包含以下成员函数:
- 一个析构函数
- 复制构造函数,
- operator =(assignment)
醇>
这是真的吗?如果复制对象没有意义怎么办?
如果指针数据成员指向不需要复制或无法更改的内容,该怎么办?
我举一个具体的例子:一个人出生在某个日期;日期是一个对象,它包含一天的值或一周中的哪一天。 我不想复制"一个人,但即使我必须,他们也不应该指向同一个Date对象吗?
如果是真的,为什么?
答案 0 :(得分:5)
指针数据成员可能意味着不同的东西。如果指针只是观察指针(对于其他地方管理的对象),那么编译器生成的复制构造函数和运算符(它只是复制指针的值)绝对没有问题。这里的潜在问题是指针可能比对象寿命更长,使其成为悬空指针。
如果它是指向堆上分配并由this
管理的内存的指针,则必须确保正确完成复制。简单地说不实现copy(构造函数和运算符)不是一个选项,因为编译器会自动创建它们,而那些很可能不会做你想要的。自2011年以来(使用C ++ 11),您当然可以=delete
复制和/或实现移动(构造函数和运算符)。
然而,最明智的做法是避免这样的指针支持std::unique_ptr
或std::vector
等数据管理类。
答案 1 :(得分:2)
这个词与#34;应该"之间有很大的不同。和#34;必须"。当我阅读你提出的文本时,这意味着我应该强烈考虑做这三件事,而不是绝对必要。逻辑,经验和可行性将胜过诸如适当时的指导原则。
话虽如此,如果它有意义,那么在你的班级中拥有这三件事总是好的。
答案 2 :(得分:0)
在你的日期示例中,那不应该是指针。如果是指针,则
你得到一个临时或副本,析构函数是做什么的?致电
日期对象上的delete
?如果您拨打delete
两次(现在有2个
对象指针,它的未定义行为。
关于 NOT 要执行的操作的示例:
class Persson
{
public:
Persson( string name, string date )
: m_name(name)
{
m_date = new Date;
ParseDate( *m_date, date );
}
~Persson()
{
delete m_date;
}
private:
string m_name;
Date* m_date;
};
如果你复制了一份Persson
,那就会出错
很容易得到一份副本,暂时无处不在。
一种可能性是指针生命周期由其他人管理,
在这种情况下,指针可以看作更多的句柄,然后它就可以了
定义copy-constructor,asignment-operator和析构函数。
除非生命由其他人管理,否则你应该
根本不使用指针,要么直接使用值,要么使用智能指针。
不太好的例子:
class Persson
{
public:
Persson( string name, string date )
: m_name(name)
{
m_date = make_shared<Date>();
ParseDate( *m_date.get(), date );
}
private:
string m_name;
shared_ptr<Date> m_date;
};
更好的例子
class Persson
{
public:
Persson( string name, string date )
: m_name(name)
{
ParseDate( m_date, date );
}
private:
string m_name;
Date m_date;
};
总是在C ++中使用价值语义,它就是为此做的 看看Rule of Zero