`
weihe6666
  • 浏览: 430108 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Operator=

    博客分类:
  • C++
C++ 
阅读更多
Operator=


赋值构造函数,问题1:为何返回类型是类,即return *this;
                     问题2:为何要对自身判断,怎么判断以防止赋值给自己?
                     问题3:自己定义赋值构造函数,要对那些数据赋值?

带着这些问题,看看下面的例子:

问题1:为何返回类型是类,即return *this;

#include <iostream>
using namespace std;

class String {
public:
	String();
	String(const char *value);    // 函数定义参见条款11
	~String();                    // 函数定义参见条款11
    
	void operator=(const String& rhs);
	void Print() const;

private:
	char *data;
};

String::String( const char *value )
{
	if (value) {
		data = new char[strlen(value) + 1];
		strcpy(data, value);
	}
	else {
		data = new char[1];
		*data = '\0';
	}

}

String::String()
{
	data = new char[1];
   *data = '\0';
}


String::~String()
{
 //delete [] data;
}



void String::operator=( const String& rhs )
{
	delete [] data;
	//allocate new memory 
	data = new char[sizeof(rhs.data)+1];
	strcpy(data,rhs.data);

	//return *this;
}

void String::Print() const
{
	cout << "The content is :" << data << endl;
}


int main()
{
	String a = "hello";
	String b = "world";
	String c = "hewei";
	a.Print();
	c = b = a;
	b.Print();
	return 0;
}


这个例子可以通过编译,但是不能运行,原因何在?

此赋值构造函数为:
void operator=(const String& rhs);
注意返回类型为void,那么c = b = a;就会出错。

因为c = b = a;等价于c.operator=(b.operator=(a.operator=("hello"))); operator=结合性由右向左,a.operator=("hello")结果是:a.data = "hello";但是a.operator=("hello")经过赋值构造函数后并没有返回值,就无法在继续赋值给b。

因此赋值构造函数必需有返回值,且返回值为类本身的引用。

其正确的赋值构造函数写法如下:
String& operator=(const String& rhs);
String& String::operator=( const String& rhs )
{
	if(this == &rhs)
		return *this;
  delete [] data;
  //allocate new memory 
  data = new char[sizeof(rhs.data)+1];
  strcpy(data,rhs.data);

  return *this;
}


问题2:为何要对自身判断,怎么判断以防止赋值给自己?

上面的例子:若赋值构造函数为:
String& operator=(const String& rhs);
String& String::operator=( const String& rhs )
{
	//if(this == &rhs)
	//	return *this;
  delete [] data;
  //allocate new memory 
  data = new char[sizeof(rhs.data)+1];
  strcpy(data,rhs.data);

  return *this;
}


当执行到语句:a = a;就会出现问题:
*this  data ------------> "hello\0"
                  /
                 /
rhs    data -----

赋值运算符做的第一件事是用delete删除data,其结果将如下所示:

*this  data ------------> ???
                   /
                  /
rhs    data -----

现在,当赋值运算符对rhs.data调用strlen时,结果将无法确定。这是因为data被

删除的时候rhs.data也被删除了,data,this->data 和rhs.data 其实都是同一个

指针!从这一点看,情况只会越变越糟糕。

现在可以知道,解决问题的方案是对可能发生的自己给自己赋值的情况先进行检查

,如果有这种情况就立即返回.

问题是如何判断两个对象“相同”??

确定对象身份是否相同的方法是用内存地址。采用这个定义,两个对象当且

仅当它们具有相同的地址时才是相同的。这个定义在c++程序中运用更广泛,可能

是因为它很容易实现而且计算很快。

其判断形势为:
if(this == &rhs)
return *this;

问题3:自己定义赋值构造函数,要对那些数据赋值?


分享到:
评论

相关推荐

    解析c++中的默认operator=操作的详解

    在c++中,如果没有定义operator=操作,编译器会提供一个默认的operator=操作。由于operator=操作和拷贝构造函数的功能类似,都执行拷贝操作。因此,编译器也分提供无用的默认operator=操作和非无用的默认operator=...

    operator=赋值检测学习

    operator=赋值自我检测,小程序,给自己参考学习

    为什么operator=操作符返回引用.docx

    为什么operator=操作符返回引用

    如何继承“ operator =”

    它是继承但隐藏的,请参见此堆栈溢出问题的答案:“运算符=和在C ++中没有继承的函数?” [^]。

    摩托罗拉C++面试题

    子类继承父类大部分的资源,不能继承的有构造函数,析构函数,拷贝构造函数,operator=函数,友元函数等等 15.为什么要引入抽象基类和纯虚函数? 主要目的是为了实现一种接口的效果。 16.介绍一下模板和容器。如何...

    boilerplate.dart:轻松实现示例方法的Dart助手(hashCode,operator ==,toString)

    // .toString, .hashCode, .operator== final List&lt;int&gt; js; // and copy({ i, js }) Foo ( this . i , this . js ); // with no extra effort.}var foo = new Foo ( 1 , [ 2 , 3 ]);assert(foo == new Foo ( 1 , ...

    浅谈C++虚重载操作符 virtual operator= 的使用方法

    本文以赋值操作符operator=举例。 派生类中要重定义基类虚函数,要注意参数必须为基类引用类型,否则与基类中虚函数是完全不同的,无法进行预期的动态绑定。 派生类除了重定义基类的虚操作符,还要定义自身的操作符...

    分数计算器

    bool operator==(int n,Fraction &c); bool operator==(Fraction &c,Fraction &f); bool operator!=(Fraction &c,Fraction &f); bool operator!=(int n,Fraction &c); bool operator&lt;=(Fraction &c,Fraction &f); ...

    C++ 模板写的短小字符串类,用于替换字符数组和std::string

    friend std::ostream & operator(std::ostream& os, const TinyString&lt;K&gt;& str); template, size_t L&gt; friend bool operator == (const TinyString&lt;K&gt;& s1, const TinyString&lt;L&gt;& s2); //...... uint8...

    Python程序基础:列表和元组典型案例.pptx

    if operator not in operator_list: #输入的运算符不是四则运算符 print("输入的运算符有误,请输入四则运算符!") #输出提示语 else: #输入的运算符属于四则运算符 if operator == '+': #运算符为“+” result = ...

    C++ HTTP - Reset32

    rest32======rest32是从C + +的Windows上调用REST Web服务](http://en.wikipedia.org/wiki/Representational_State_Transfer#RESTful_web_services)库。...这将是一段时间,在此之前,生产准备,但我是饲料中的公共...

    词法分析器java

    public ArrayList operator; static HashMap BRACKET; static HashMap KEYWORD; static HashMap SEMICOLON; static HashMap OPERATOR; public analyetest() { this.KEYWORD = new HashMap(); this....

    C++ HTTP Reset32

    C++ HTTP Reset32,HTTP可安装项目,提供大家下载!

    面向对象程序设计C++

    Mycomplex& operator=(const Mycomplex& rhs); Mycomplex& operator+=(const Mycomplex& rhs); Mycomplex& operator-=(const Mycomplex& rhs); Mycomplex& operator*=(const Mycomplex& rhs); Mycomplex& operator/=...

    ORM-Dapper+DapperExtensions 示例全代码

    var pgMain = new PredicateGroup { Operator = GroupOperator.Or, Predicates = new List() }; var pga = new PredicateGroup() { Operator = GroupOperator.And, Predicates = new List() }; pga.Predicates....

    用java写的凯撒加密器源码

    int operator = input.nextInt(); if(operator == 1){ System.out.print("请输入待加密的字符串:"); String source = input.next(); Encryption encryption = new Encryption(); String encrytStr ...

    字符串、运算符重载

    String operator =(String &s); String operator +(String &s); int operator &gt;(String &s); int operator &lt;(String &s); int operator &lt;=(String &s); int operator &gt;=(String &s); String operator++(); ...

    单链表的插入、删除、逆转等实现

    template&lt;class T&gt; //定义在“LinkedChain.h” struct ChainNode //链表结点类的定义 ... bool operator==(T x) { return data==x; }//重载函数,判相等 bool operator!=(T x) { return data!=x; } };

Global site tag (gtag.js) - Google Analytics