任何人都可以在下面提到的代码中解释我的分配操作员。我有
问题1 :为什么该赋值运算符返回引用对象[我知道这用于此类c1 = c2 = c3
,但这是如何工作的]
Quest 2 :我创建了动态指针tempName
,但我没有释放内存,因此存在内存泄漏。我怎么解决这个问题。或者举个例子,如果你有。
任务3 :我已在名称中指定了tempName
,因此如果我在返回前删除tempName
,则名称指向tempName
,那么会发生什么
Contact& operator=( const Contact& rhs ) {
char* tempName = new char[ strlen( rhs. name ) + 1] ;
delete[ ] name;
name = tempName;
strcpy( name, rhs. name ) ;
age = rhs. age;
return *this;
}
答案 0 :(得分:2)
当您返回对象的引用时,您可以将其放在赋值的左侧以分配另一个值。所以,我认为有两个原因。
(1)避免不必要的复制。
(2)C ++中赋值的默认行为,你可以做到
a = (b = c)
或
(a = b) = c
即使返回值,第一种形式也可以。 但对于第二个,您必须返回对该值的引用,以使其行为与正常的C ++分配相同。†
是的,它有内存泄漏。除非您删除析构函数中的name
。
name
和tempName
指向同一地址。因此,删除tempName
将删除name
指向的内容。不要这样做。
此外,使用C ++,为什么不使用std::string
而不是C风格的字符串,让std::string
来管理它的内存。
†当然,您可以违反C ++方式并为操作员提供自己的行为。但不建议这样做。
答案 1 :(得分:1)
避免不必要的复制。即使你返回一个值,链接也会起作用,所以它并不是绝对必要的。返回引用主要是模仿本机类型的赋值,其中编译器返回l值而不是r值。甚至编译器生成的赋值运算符也会返回引用。
删除析构函数中的内存。
如果您删除然后返回,则来电者将无法使用它。
答案 2 :(得分:0)
在C ++中(如在C中),assignement返回一个值。事实上,a = b = c
只是a = (b = c)
,因为b = c
会返回b的新值。
这就是为什么要避免破坏语言语义,分配操作必须在分配后返回对象的引用。
在失去对指针的访问权限之前,必须释放内存。一种简单的方法是封装到对象中的原始指针,并在析构函数(封装对象)中执行删除操作。这就是std::unique_ptr
的原因。但在此用例中,tempname
已受到对象的name
属性的影响。只需删除name
析构函数中的Contact
。
this->name
似乎是一个原始指针,恰好指向新分配的tempname
。如果您在返回前删除tempname
,this->name
将指向已释放的内存=>它叫做悬空指针。
答案 3 :(得分:0)
链接分配是一种语法,您可以像1
2
1-[(
3
1-[({
4
1-[({5-[
5
1-[({5-[(
4
1-[({5-[(4'-cyanobiphenyl-4-yl)
3
1-[({5-[(4'-cyanobiphenyl-4-yl)oxy]
2
1-[({5-[(4'-cyanobiphenyl-4-yl)oxy]pentyl}
1
1-[({5-[(4'-cyanobiphenyl-4-yl)oxy]pentyl}oxy)
0
1-[({5-[(4'-cyanobiphenyl-4-yl)oxy]pentyl}oxy)carbonyl]
Level 0 has reached
testing ends'
一样将值分配给多个持有者。你可以这样理解它:a = b = c
因为它从右到左执行它堆叠。链接可以通过按值返回以及通过引用返回来实现。
现在回到你的问题“为什么参考?”。参考用于优化。按值返回时,将创建值的副本并将其发送回调用代码。
请考虑以下代码以便更好地理解:
b=c; a=b;
您不必使用tempName分配内存,而是可以使用“name”本身。请参阅下面的代码段:
class A
{
int _a;
public:
void setA(int a){ _a = a; }
A() :_a(0){}
A operator=(const A&);// here we are returning by value
A& operator=(const A&);// here we are returning by reference.
//Both support chaining but using reference avoids unnecessary copy
};
delete[ ] name;
由于您的代码(不理想)名称和char* name = new char[ strlen( rhs. name ) + 1];
指向相同的内存位置。删除tempName
会导致tempName
的堆损坏,这意味着当您尝试访问name
时,程序将会中断。
我希望有所帮助。评论进一步澄清。