2012-04-28 129 views
0

请帮助完成赋值重载函数的执行。赋值=运算符超载

这里是指令:

赋值运算符(=),这将源字符串复制到目标字符串。请注意,目标的大小需要调整为与来源相同。

加法(+)和赋值(=)操作符都需要能够级联操作。这意味着String3 = String1 + String2String1 = String2 = String3应该工作。

这里是我的.cpp文件:

int MyString::Length() 
{ 
     int counter(0); 

     while(String[counter] != '\0') 
     { 
      counter ++; 
     } 
    return (counter); 
} 

MyString& MyString::operator=(const MyString& rhs) 
{ 

     if(this != &rhs) 
     { 

       delete [] String; 
       String = new char[rhs.Length()]; 

      for(int i = 0; i <rhs.Length()+1 ; i++) 
      {  
        String[i] = rhs.String[i]; 
      }  


     } 
     return *this; 

} 

这就是所谓的通过的main.cpp文件:

的String1 = String2的= STRING3;

我觉得好像我失去了一些东西。帮助!

+2

在例外的脸想想正确性! – dirkgently 2012-04-28 21:21:12

+0

具体问题是什么? – 2012-04-28 21:22:20

+3

您正在保留'this-> Size'字符,您正在复制'this-> counter'字符。不应该是'rhs.Size'或'rhs.counter'? – 2012-04-28 21:25:17

回答

2

我想Stringchar*。也许那么,Size,这是新的长度,需要设置为rhs的长度,这是新的字符串。所以它应该是rhs.Size,而不是这个 - >大小,这可能是这种情况。请注意,终止空字符也应该在char数组大小中考虑。

之后,您可以输入循环,再次照顾所有的字符,并终止空字符。鉴于我们不知道counter是什么,并假设它是没有空字符的新字符串长度(因此+ 1会计),我想这个循环没有任何问题。

+0

所以当我说String = new char [Size.Length()]这是你的意思吗?或者应该像这样声明,Size = rhs.Size;是的,我疯狂的循环,但我已经编辑它。 – user1363061 2012-04-28 22:02:27

+0

'delete [] String'后,应该这样做:'Size = rhs.Size'。在完成之后,新的'String'应该是'String = new char [rhs.Size]',或者只是'String = new char [Size]',因为'Size'现在等于'rhs.Size' 。如果Size忽略终止字符,请添加一个。这里的要点是你需要使任何成员变量等于作为参数传递给赋值运算符的对象。 – 2012-04-28 22:07:55

+1

很高兴知道你错了什么。但最后你必须使用复制和交换(或者解决如何以异常安全的方式编写它)。复制和交换成语也只有三行,所以一旦你知道它,写起来也更容易。 – 2012-04-28 22:16:30

4

结帐copy and swap idiom

您的代码存在的问题之一是它不是异常安全的。
它甚至不符合basic exception guarantee

如果在新操作过程中抛出,则对象将处于完全无法使用的状态。如果事实处于危险状态,因为如果在堆栈展开期间因为异常而调用析构函数,您将得到未定义的行为,因为析构函数将再次调用String上的删除。

的对象上的所有方法,应该在三个阶段行动:

  1. 尽一切可以抛出,但不改变对象的工作。
    • 所以,如果你抛出物体保持良好的状态。
  2. 将您在(1)中创建的数据以异常安全的方式与对象数据进行交换。
    • 这就是为什么swap()方法是无抛出
  3. 整理好,并删除。
    • 由于对象再次处于一致状态,可以抛出哪个对象。

复制和交换成语封装了这些步骤,而在很好的易于使用的技术。

+0

“整洁和删除”不应该需要完成,因为在C++中我们使用智能指针。 (你是吧?) – 2012-04-28 21:56:33

+0

这是正确的 – user1363061 2012-04-28 22:00:08

+0

@MooingDuck:智能指针是一种实现技术。这些原则仍然存在,有一个整洁和阶段。另外String实际上是一个容器,因此智能指针并不适用。智能指针和容器是不同但适用于内存管理的并行技术。 – 2012-04-29 09:13:16

1

在开始赋值运算符重载之前,让我们看看运算符在C++中的重载。在面向对象编程中,运算符重载 - 通常称为运算符ad hoc多态 - 是多态的一个特例,其中不同的运算符根据它们的参数有不同的实现。运算符重载一般由语言,程序员或两者来定义。使用操作符重载是因为它允许开发人员使用更接近目标域的符号进行编程,并允许用户定义的类型与内置于语言中的类型具有类似的语法支持级别。例如,在科学计算中很常见,它允许用与纸上相同的语法来操作数学对象的计算表示。可以使用函数调用来模拟对象重载。

我们现在该怎么重载赋值运算符(=),

我们这样做赋值运算符重载后,我们随后将能够分配我们的自定义数据类型的两个变量。让我们来看看下面的例子:

// Operator overloading in C++ 
//assignment operator overloading 
#include<iostream> 
using namespace std; 

class Employee 
{ 
private: 
int idNum; 
double salary; 
public: 
Employee () { 
    idNum = 0, salary = 0.0; 
} 

void setValues (int a, int b); 
void operator= (Employee &emp); 

}; 

void Employee::setValues (int idN , int sal) 
{ 

salary = sal; idNum = idN; 

} 

void Employee::operator = (Employee &emp) // Assignment operator overloading function 
{ 
salary = emp.salary; 
} 

int main () 
{ 

Employee emp1; 
emp1.setValues(10,33); 
Employee emp2; 
emp2 = emp1;  // emp2 is calling object using assignment operator 

} 

现在让我们来解释一下这个代码重载“=”操作符,我们使用功能“setValues方法”,这是一个分配的值,以“国际化域名”和“SAL” “Employee”类的公共成员函数,现在我们的重点是定义为“operator =”的重载函数。在这个函数中,我们将薪水的值分配给同一个类的另一个变量,这样我们就可以直接在我们的main()函数中使用赋值操作符。现在,您可以在main()中看到,我们有两个变量emp1和emp2,类型为Employee,我们可以直接在最后一行代码中使用赋值运算符,这全是因为运算符“=”的赋值运算符重载或运算符重载。 ”。