我已经开始用C ++开发了,我对复制构造函数和赋值运算符有疑问。
我有这堂课:
class MyTime
{
private:
unsigned char _hour;
unsigned char _minute;
float _second;
signed char _timeZone;
unsigned char _daylightSavings;
double _decimalHour;
public:
MyTime(unsigned char hour, unsigned char minute, float second, signed char timeZone, unsigned char daylightSavings);
MyTime(const MyTime& copySource);
MyTime& operator=(const MyTime& source);
~MyTime();
unsigned char getHour();
unsigned char getMinute();
float getSeconds();
signed char getTimeZone();
unsigned char getDayLightSavings();
double getDecimalHour();
};
复制构造函数和赋值运算符实现:
MyTime::MyTime(const MyTime& copySource)
{
this->_hour = copySource._hour;
this->_minute = copySource._minute;
this->_second = copySource._second;
this->_timeZone = copySource._timeZone;
this->_daylightSavings = copySource._daylightSavings;
}
MyTime& MyTime::operator=(const MyTime& source)
{
this->_hour = source._hour;
this->_minute = source._minute;
this->_second = source._second;
this->_timeZone = source._timeZone;
this->_daylightSavings = source._daylightSavings;
return *this;
}
是否需要这些实施?
我需要确保在分配MyTime实例时,它会创建一个带有其值的新实例。
答案 0 :(得分:2)
没有。您的类不需要复制构造函数,赋值运算符或析构函数。编译器生成的将完全符合您的要求。
此外,从样式POV,您不需要所有“this->”要访问类成员的东西,除非你为局部变量选择坏名称,或者正在进行complex template-related stuff。
答案 1 :(得分:2)
您的复制构造函数和赋值运算符只是将copySource
和source
中的值分别复制到您的实例中。
您不创建新实例,只需使用copySource
和source
覆盖您的实例值。
目前,您的类甚至不需要编写复制构造函数和赋值运算符,因为编译器会隐式为您生成它们。 这是C ++语言的一个特性,我建议阅读更多关于这个here: Copy constructors in C++的内容(ndMarco:我知道这可能不是最容易学习的资源,但它是最完整和准确编写的资源之一)。
将每个成员变量从一个实例复制到另一个不是deep-copy问题,因此不需要您采取任何操作。
作为学习的后续工作,请查看rule of three/five/zero。从三级规则开始(理解为什么你的课程不需要其中任何一个以及如果需要其中一个会发生什么)然后继续理解C ++ 11概念。
最后一个次要的事情:在C ++中不需要使用冗长的this->member_variable
,除非您需要明确指出您是指成员变量而不是本地变量,例如
class MyClass {
public:
int value = 33;
void function() {
int value = 42; // Now there's confusion
std::cout << value; // 42
}
};
所以在你的情况下this->
不是必需的。无论如何,作为一种风格偏好,您仍然可以使用它来表明您指的是该类的成员变量。请注意这个小警告。这是为了增加你不应该以同样方式命名你的本地变量和类成员的事实(这是一种可怕的做法)。
仍有许多事情可以添加或构建在这些概念上,但他们会引导这篇文章偏离主题。只要想一想这些初步概念,你就可以称之为一天。
答案 2 :(得分:1)
不,您的代码等同于默认的复制构造函数和赋值运算符。编译器将根据需要生成这些。根据经验,如果使用动态内存或某些没有复制语义的对象,则需要定义自己的版本。
举一个简单的例子,如果你在构造函数中编写new
,你必须在析构函数中编写匹配的delete
,然后由rule of three编写,你将不得不这样做带有复制构造函数和赋值运算符的东西。如果您避免手动管理内存,则无需担心这些内容。
答案 3 :(得分:1)
不要这样做,因为你的编译器应该为你生成它们。但是,并非所有类别都是如此。编译器生成的复制构造函数/赋值运算符基本上只使用=
运算符来处理所有内容,如果您使用指针和动态内存,这不是一个好例子:
拿一个字符串类。您有一个char*
,您可以在字符串类中重新分配内部函数,并使用copy
,e.t.c等函数进行分配。
但是,如果类似string
的类省略了复制构造/赋值运算符,编译器应该自动创建一个,这与你想要的不同,它只是将你的指针指向类的指针被复制,这将导致大的错误,因为一旦修改了类,你的字符串也将被修改,因为它们都指向同一个内存。因此,对于您不希望编译器在所有成员上使用简单operator=
的类,您应该定义复制构造函数/ operator = ...否则只要您拥有它就没有必要一个好的编译器
注意:您不需要this->
来访问成员,因为您没有从模板化类中继承它们。