36 C++ - 赋值(=)运算符重载

简介: 36 C++ - 赋值(=)运算符重载

赋值符常常初学者的混淆。这是毫无疑问的,因为’=’在编程中是最基本的运算符,可以进行赋值操作,也能引起拷贝构造函数的调用。

class Person{
  friend ostream& operator<<(ostream& os,const Person& person){
    os << "ID:" << person.mID << " Age:" << person.mAge << endl;
    return os;
  }
public:
  Person(int id,int age){
    this->mID = id;
    this->mAge = age;
  }
  //重载赋值运算符
  Person& operator=(const Person& person){
    this->mID = person.mID;
    this->mAge = person.mAge;
    return *this;
  }
private:
  int mID;
  int mAge;
};
//1. =号混淆的地方
void test01(){
  Person person1(10, 20);
  Person person2 = person1; //调用拷贝构造
  //如果一个对象还没有被创建,则必须初始化,也就是调用构造函数
  //上述例子由于person2还没有初始化,所以会调用构造函数
  //由于person2是从已有的person1来创建的,所以只有一个选择
  //就是调用拷贝构造函数
  person2 = person1; //调用operator=函数
  //由于person2已经创建,不需要再调用构造函数,这时候调用的是重载的赋值运算符
}
//2. 赋值重载案例
void test02(){
  Person person1(20, 20);
  Person person2(30, 30);
  cout << "person1:" << person1;
  cout << "person2:" << person2;
  person2 = person1;
  cout << "person2:" << person2;
}
//常见错误,当准备给两个相同对象赋值时,应该首先检查一下这个对象是否对自身赋值了
//对于本例来讲,无论如何执行这些赋值运算都是无害的,但如果对类的实现进行修改,那么将会出现差异;
//3. 类中指针
class Person2{
  friend ostream& operator<<(ostream& os, const Person2& person){
    os << "Name:" << person.pName << " ID:" << person.mID << " Age:" << person.mAge << endl;
    return os;
  }
public:
  Person2(char* name,int id, int age){
    this->pName = new char[strlen(name) + 1];
    strcpy(this->pName, name);
    this->mID = id;
    this->mAge = age;
  }
#if 1
  //重载赋值运算符
  Person2& operator=(const Person2& person){
    //注意:由于当前对象已经创建完毕,那么就有可能pName指向堆内存
    //这个时候如果直接赋值,会导致内存没有及时释放
    if (this->pName != NULL){
      delete[] this->pName;
    }
    this->pName = new char[strlen(person.pName) + 1];
    strcpy(this->pName,person.pName);
    this->mID = person.mID;
    this->mAge = person.mAge;
    return *this;
  }
#endif
  //析构函数
  ~Person2(){
    if (this->pName != NULL){
      delete[] this->pName;
    }
  }
private:
  char* pName;
  int mID;
  int mAge;
};
void test03(){
  Person2 person1("John",20, 20);
  Person2 person2("Edward",30, 30);
  cout << "person1:" << person1;
  cout << "person2:" << person2;
  person2 = person1;
  cout << "person2:" << person2;
}

如果没有重载赋值运算符,编译器会自动创建默认的赋值运算符重载函数。行为类似默认拷贝构造,进行简单值拷贝。

目录
相关文章
|
1月前
|
存储 编译器 C++
【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)
本文介绍了C++中类和对象的高级特性,包括取地址运算符重载、构造函数的初始化列表、类型转换、static修饰成员、友元、内部类及匿名对象等内容。文章详细解释了每个概念的使用方法和注意事项,帮助读者深入了解C++面向对象编程的核心机制。
105 5
|
3月前
|
C++
C++(十五) 运算符重载
C++中的运算符重载允许对已有运算符的功能进行重新定义,从而扩展语言功能、简化代码并提升效率。重载遵循特定语法,如 `friend 类名 operator 运算符(参数)`。重载时需注意不可新增或改变运算符数量、语义、优先级、结合性和返回类型。常见示例包括双目运算符 `+=` 和单目运算符 `-` 及 `++`。输入输出流运算符 `&lt;&lt;` 和 `&gt;&gt;` 也可重载。部分运算符只能作为成员函数重载。
|
6月前
|
C++ 容器
C++之deque容器(构造、赋值、大小、插入与删除、存取、排序)
C++之deque容器(构造、赋值、大小、插入与删除、存取、排序)
|
6月前
|
C++ 容器
C++字符串string容器(构造、赋值、拼接、查找、替换、比较、存取、插入、删除、子串)
C++字符串string容器(构造、赋值、拼接、查找、替换、比较、存取、插入、删除、子串)
|
6月前
|
存储 编译器 C++
【C++】:拷贝构造函数和赋值运算符重载
【C++】:拷贝构造函数和赋值运算符重载
34 1
|
5月前
|
自然语言处理 程序员 C++
C++基础知识(五:运算符重载)
运算符重载是C++中的一项强大特性,它允许程序员为自定义类型(如类或结构体)重新定义标准运算符的行为,使得这些运算符能够适用于自定义类型的操作。这样做可以增强代码的可读性和表达力,使得代码更接近自然语言,同时保持了面向对象编程的封装性。
|
5月前
|
Java 程序员 C++
|
5月前
|
编译器 C++
【C++】详解运算符重载,赋值运算符重载,++运算符重载
【C++】详解运算符重载,赋值运算符重载,++运算符重载
|
6月前
|
编译器 C++
【C++】类和对象③(类的默认成员函数:赋值运算符重载)
在C++中,运算符重载允许为用户定义的类型扩展运算符功能,但不能创建新运算符如`operator@`。重载的运算符必须至少有一个类类型参数,且不能改变内置类型运算符的含义。`.*::sizeof?`不可重载。赋值运算符`=`通常作为成员函数重载,确保封装性,如`Date`类的`operator==`。赋值运算符应返回引用并检查自我赋值。当未显式重载时,编译器提供默认实现,但这可能不足以处理资源管理。拷贝构造和赋值运算符在对象复制中有不同用途,需根据类需求定制实现。正确实现它们对避免数据错误和内存问题至关重要。接下来将探讨更多操作符重载和默认成员函数。
|
6月前
|
算法 C++ 容器
C++之vector容器操作(构造、赋值、扩容、插入、删除、交换、预留空间、遍历)
C++之vector容器操作(构造、赋值、扩容、插入、删除、交换、预留空间、遍历)
308 0