标签:std printf strcmp als 默认 sizeof 函数返回值 应该 项目
所谓重载,就是重新赋予新的含义
class Complex
{
public:
Complex(int a = 0, int b = 0)
{
this->a = a;
this->b = b;
}
void printCom()
{
cout << a << " + " << b << "i" << endl;
}
int a;
int b;
};
Complex operator+(Complex &c1, Complex &c2)
{
Complex tmp(c1.a + c2.a, c1.b + c2.b);
return tmp;
}
void main()
{
Complex c1(1, 2), c2(3, 4);
Complex c3;
// 运算符+ 重载
c3 = c1 + c2;
c3.printCom();
system("pause");
}
不能重载的运算符
. :: .* ?: sizeof
二元运算符: Complex operator+(Complex &c1, Complex &c2)
一元运算符:Complex& operator++(Complex &c1)
二元运算符: Complex operator-(Complex &c2)
一元运算符:Complex& operator--()
实现运算符(+、-、++、--、<<、=)重载
class Complex
{
public:
Complex(int a = 0, int b = 0)
{
this->a = a;
this->b = b;
}
void printCom()
{
cout << a << " + " << b << "i" << endl;
}
// 友元函数重载 +
friend Complex operator+(Complex &c1, Complex &c2);
// 友元函数重载 前置++
friend Complex& operator++(Complex &c);
// 友元函数重载 后置++
friend Complex operator++(Complex &c, int);
// 友元函数重载 <<
//friend void operator<<(ostream &cout, Complex &c);
friend ostream& operator<<(ostream &out, Complex &c);
// 成员函数重载 -
Complex operator-(Complex &c2)
{
Complex tmp(this->a - c2.a, this->b - c2.b);
return tmp;
}
// 成员函数重载 前置--
Complex& operator--()
{
this->a --;
this->b --;
return *this;
}
// 成员函数重载 后置--
Complex operator--(int)
{
// 返回自身 *this
Complex tmp = *this;
this->a--;
this->b--;
return tmp;
}
private:
int a;
int b;
};
// 使用全局函数(友元函数)实现 运算符 + 重载
Complex operator+(Complex &c1, Complex &c2)
{
Complex tmp(c1.a + c2.a, c1.b + c2.b);
return tmp;
}
// 使用全局函数(友元函数)实现 运算符前置++ 重载
Complex& operator++(Complex &c)
{
c.a++;
c.b++;
return c;
}
// 使用全局函数(友元函数)实现 运算符后置++ 重载
// int 占位符,避免函数重载出错
Complex operator++(Complex &c, int)
{
// 先返回,使用临时变量保存后再返回
Complex tmp = c;
c.a++;
c.b++;
return tmp;
}
// 使用全局函数(友元函数)实现 运算符 << 重载
// void operator<<(ostream &out, Complex &c)
// {
// out << c.a << " + " << c.b << "i" << endl;
// }
ostream& operator<<(ostream &out, Complex &c)
{
out << c.a << " + " << c.b << "i" ;
return out;
}
void main()
{
Complex c1(1, 2), c2(3, 4);
Complex c3, c4;
// 二元运算符
{
// 使用全局函数(友元函数)实现 运算符+ 重载
c3 = c1 + c2;
cout << "operator+ : ";
c3.printCom();
// 使用成员函数 实现 运算符- 重载
c4 = c1 - c2;
cout << "operator- : ";
c4.printCom();
}
// 一元运算符
{
// 使用全局函数(友元函数)实现 运算符前置++ 重载
// ++a, 先++,(修改后)再返回自身
// Complex& operator++(Complex &c)
++c1;
cout << "operator++ : ";
c1.printCom();
// 使用成员函数 实现 运算符前置-- 重载
// Complex& operator--()
--c2;
cout << "operator-- : ";
c2.printCom();
// 使用全局函数(友元函数)实现 运算符后置++ 重载
// a++, (修改前)先返回自身,再++
// Complex operator++(Complex &c, int)
c1++;
cout << "operator++ : ";
c1.printCom();
// 使用成员函数 实现 运算符后置-- 重载
// Complex operator--(int)
c2--;
cout << "operator-- : ";
c2.printCom();
}
// 重载运算符 <<
{
// 使用全局函数(友元函数)实现 运算符 << 重载
// << 参数1: cout 参数2:c1
// cout定义: ostream cout, *_Ptr_cout;
// void operator<<(ostream &out, Complex &c)
//cout << c1;
// 使用成员函数 实现 运算符 << 重载
// cout.operator --> 需在 ostream 类中定义成员函数,所以在这不能使用
// 链式编程支持
// 函数返回值当左值,需要返回一个引用
// ostream& operator<<(ostream &out, Complex &c)
cout << "operator<< : ";
cout << c1 << " test operator<<" << endl;
}
system("pause");
}
总结:
一般使用成员函数实现运算符重载
使用友元函数(全局函数)实现运算符重载的场景
友员函数重载运算符常用于运算符的左右操作数类型不同的情况 ;
在第一个参数需要隐式转换的情形下,使用友员函数重载运算符是正确的选择;
C++中不能用友员函数重载的运算符有 : = () [] ->
重载运算符 [] 、=、==、!=
重载赋值运算符=
class Name
{
public:
Name(char* str)
{
len = strlen(str);
pname = (char*)malloc(len + 1);
strcpy(pname, str);
}
Name(const Name &obj)
{
len = obj.len;
pname = (char*)malloc(len + 1);
strcpy(pname, obj.pname);
}
~Name()
{
if (pname != NULL)
{
free(pname);
pname = NULL;
len = 0;
}
}
// 重载 = 运算符,实现从浅拷贝到深拷贝
// name3 = name1
Name& operator=(Name &obj)
{
// 1. 释放旧的内存
if (this->pname != NULL)
{
delete[] pname;
len = 0;
}
// 2. 根据obj分配内存大小
this->len = obj.len;
this->pname = new char[len + 1];
// 3. copy内存实现深拷贝
strcpy(pname, obj.pname);
// 返回 Name 自身
return *this;
}
private:
char* pname;
int len;
};
void test()
{
Name name1("testname");
Name name2 = name1; // 编译器提供默认的拷贝构造函数
// 重载 = 运算符,实现从浅拷贝到深拷贝
// void operator=(Name &obj)
// 支持链式编程 Name& operator=(Name &obj)
Name name3("oldname");
name3 = name1;
}
void main()
{
test();
system("pause");
}
总结:
重载函数调用符()
class MyClass
{
public:
MyClass(int a=0, int b=0)
{
this->a = a;
this->b = b;
}
int Func(int a, int b)
{
return (a*a + b*b);
}
int operator()(int a, int b)
{
return (a*a + b*b);
}
private:
int a;
int b;
};
void main()
{
// 构造函数
MyClass c1(1, 2);
// 成员函数
MyClass c2;
c2.Func(3, 4);
// ()重载
MyClass c3;
c3(5, 6);
system("pause");
}
为什么不要重载&&和||操作符
&&和||是 C++中非常特殊的操作符;
&&和||内置实现了短路规则;
操作符重载是靠函数重载来完成的;
操作数作为函数参数传递;
C++的函数参数都会被求值,无法实现短路规;
[] 、=、==、!=、<<、>>
注意:实际开发中应该将定义和实现分开。
// 实现一个数组类:实现重载[]、 =、 ==、 !=、 <<、 >>
class myArray
{
public:
// 有参构造函数
myArray(int length=0)
{
if (length < 0)
{
length = 0;
}
len = length;
pSpace = new int[len];
}
// 拷贝构造函数
myArray(const myArray &obj)
{
this->len = obj.len;
this->pSpace = new int[this->len];
for (int i = 0; i < len; i++)
{
this->pSpace[i] = obj.pSpace[i];
}
}
// 析构函数
~myArray()
{
if (pSpace != NULL)
{
delete[] pSpace;
pSpace = NULL;
len = -1;
}
cout << "执行析构函数" << endl;
}
int getLen()
{
return len;
}
// 重载 []
int& operator[](int index)
{
return pSpace[index];
}
// 重载 =
myArray& operator=(myArray &obj)
{
// 1. 释放旧的内存
if (this->pSpace != NULL)
{
delete[] pSpace;
len = 0;
}
// 2. 根据obj分配内存大小
this->len = obj.len;
this->pSpace = new int[len];
// 3. copy内存实现深拷贝
for (int i = 0; i < len; i++)
{
//pSpace[i] = obj.pSpace[i];
pSpace[i] = obj[i];
}
// 返回 Name 自身
return *this;
}
// 重载 ==
bool operator==(myArray &obj)
{
if (this->len != obj.len)
{
return false;
}
for (int i = 0; i < len; i++)
{
if (pSpace[i] != obj[i])
{
return false;
}
}
return true;
}
// 重载 !=
bool operator!=(myArray &obj)
{
return !(*this == obj);
}
friend istream& operator >> (istream &in, myArray &obj);
friend ostream& operator<<(ostream &out, myArray &obj);
private:
int* pSpace;
int len;
};
// 重载 >>
istream& operator >> (istream &in, myArray &obj)
{
cout << "len: " << obj.len << endl;
for (int i = 0; i < obj.len; i++)
{
printf("输入obj[%d]: ", i);
cin >> obj[i];
}
return in;
}
// 重载 <<
ostream& operator<<(ostream &out, myArray &obj)
{
for (int i = 0; i < obj.len; i++)
{
cout << obj[i] << " ";
}
return out;
}
// test
void testArr()
{
// 有参构造函数
myArray a(5);
// 拷贝构造函数
myArray b = a;
myArray c(3);
//重载运算符 []
for (int i=0; i<a.getLen(); i++)
{
//int& operator[](int index)
a[i] = i;
}
cout << a << endl;
//重载运算符 =
//myArray& operator=(myArray &obj)
c = a;
//重载运算符 ==
//BOOL operator==(myArray &obj)
if (a == c)
{
cout << "相等" << endl;
}
else
{
cout << "不相等" << endl;
}
//重载运算符 !=
//BOOL operator!=(myArray &obj)
if (a != c)
{
cout << "不相等" << endl;
}
else
{
cout << "相等" << endl;
}
//重载运算符 >> <<
myArray d(3);
//istream& operator>>(istream &in, myArray &obj)
cin >> d;
//ostream& operator<<(ostream &out, myArray &obj)
cout << d << endl;
cout << d << "--- "<< a << endl;
}
void main()
{
testArr();
system("pause");
}
<< >> != == > < =
MyString.h
#pragma once
class MyString
{
public:
// 构造
MyString(int len=0);
MyString(char* str);
MyString(const MyString &str);
// 重载 =
MyString& operator=(const char* p);
MyString& operator=(MyString &mystr);
// 重载 []
char& operator[](int index);
// 重载 == !=
bool operator==(const char* p);
bool operator!=(const char* p);
bool operator==(const MyString &mystr);
bool operator!=(const MyString &mystr);
// 重载 > <
int operator>(const char* p);
int operator<(const char* p);
int operator>(const MyString &s);
int operator<(const MyString &s);
// 重载 <<
friend ostream& operator<<(ostream &out, MyString &mystr);
// 重载 >>
friend istream& operator>>(istream &in, MyString &mystr);
// 析构
~MyString();
private:
int len;
char* str;
};
MyString.cpp
#define _CRT_SECURE_NO_WARNINGS
#include "iostream"
using namespace std;
#include "MyString.h"
// 无参构造函数
MyString::MyString(int len)
{
if (len == 0)
{
len = 0;
str = new char[len + 1];
strcpy(str, "");
}
else
{
this->len = len;
str = new char[len + 1];
memset(str, 0, len);
}
}
// 有参构造函数
MyString::MyString(char* str)
{
if (str == NULL)
{
len = 0;
str = new char[len + 1];
strcpy(str, "");
}
else
{
len = strlen(str);
this->str = new char[len + 1];
strcpy(this->str, str);
}
}
// 拷贝构造函数
MyString::MyString(const MyString &str)
{
this->len = str.len;
this->str = new char[len + 1];
strcpy(this->str, str.str);
}
// 析构函数
MyString::~MyString()
{
if (str != NULL)
{
delete[] str;
str = NULL;
len = 0;
}
}
// 重载 =
// 情况一: s = "aaa";
MyString& MyString::operator=(const char* p)
{
// 1. 释放旧的内存
if (this->str != NULL)
{
delete[] str;
len = 0;
}
// 2. 根据p分配内存大小
if (p == NULL)
{
len = 0;
str = new char[len + 1];
strcpy(str, "");
}
else
{
// 3. copy内存
this->len = strlen(p);
this->str = new char[len + 1];
strcpy(str, p);
}
// 返回自身
return *this;
}
// 情况二: s2 = s1;
MyString& MyString::operator=(MyString &mystr)
{
if (this->str != NULL)
{
delete[] str;
len = 0;
}
this->len = mystr.len;
this->str = new char[len + 1];
strcpy(str, mystr.str);
return *this;
}
// 重载 []
char& MyString::operator[](int index)
{
return str[index];
}
// 重载 <<
ostream& operator<<(ostream &out, MyString &mystr)
{
cout << mystr.str;
return out;
}
// 重载 >>
istream& operator >> (istream &in, MyString &mystr)
{
cin >> mystr.str;
return in;
}
// 重载 == !=
// 情况一: s2 == "aaa";
bool MyString::operator==(const char* p)
{
if (p == NULL)
{
if (len == 0)
{
return true;
}
else
{
return false;
}
}
else
{
if (len != strlen(p))
{
return false;
}
else
{
return !(strcmp(str, p));
}
}
}
bool MyString::operator!=(const char* p)
{
return !(*this == p);
}
// 情况二: s1 == s2;
bool MyString::operator==(const MyString &mystr)
{
if (len != mystr.len)
{
return false;
}
return !strcmp(str, mystr.str);
}
bool MyString::operator!=(const MyString &mystr)
{
return !(*this == mystr.str);
}
// 重载 > <
// 情况1: s > "aaaa";
int MyString::operator>(const char* p)
{
return strcmp(this->str, p);
}
int MyString::operator<(const char* p)
{
return strcmp(p, this->str);
}
// 情况2: s1 > s2
int MyString::operator>(const MyString &s)
{
return strcmp(this->str, s.str);
}
int MyString::operator<(const MyString &s)
{
return strcmp(s.str, this->str);
}
MyString_Test.cpp
#include "iostream"
using namespace std;
#include "MyString.h"
void test()
{
// 构造函数
MyString s1;
MyString s2("testS2");
MyString s3 = s2;
MyString s4 = "S4_test";
// 重载 =
{
//MyString& operator=(const char* p)
//MyString& operator=(MyString &mystr)
s2 = s4;
s2 = "ttttt22222";
}
// 重载 []
{
//char& operator[](int index)
s2[2] = ‘6‘;
cout << "修改后: " << s2[2] << endl;
}
// 重载 <<
{
//ostream& operator<<(ostream &out, MyString &mystr)
cout << "修改后: " << s2 << endl;
}
// 重载 == !=
{
// 情况一: s2 == "aaa";
//bool operator==(const char* p)
//bool operator!=(const char* p)
if (s2 == "tt6tt22222")
{
cout << "相等" << endl;
}
else
{
cout << "不相等" << endl;
}
if (s2 != "ss22")
{
cout << "不相等" << endl;
}
else
{
cout << "相等" << endl;
}
// 情况二: s1 == s2;
//bool operator==(const MyString &mystr)
//bool operator!=(const MyString &mystr)
MyString s5 = "tt6tt22222";
if (s2 == s5)
{
cout << "相等" << endl;
}
else
{
cout << "不相等" << endl;
}
if (s2 != s4)
{
cout << "不相等" << endl;
}
else
{
cout << "相等" << endl;
}
}
// 重载 > <
{
MyString a("aaaa");
MyString b("bbbb");
// >时返回整数,<时返回负数
//int tag = (b > "aaaa");
int tag = (a > b);
if (tag > 0)
{
cout << "大于" << endl;
}
else if(tag == 0)
{
cout << "等于" << endl;
}
else
{
cout << "小于" << endl;
}
}
// 重载 >>
{
MyString str1(128);
//istream& operator >> (istream &in, MyString &mystr)
cout << "输入字符串(回车确认):";
cin >> str1;
cout << str1;
}
}
void main()
{
test();
system("pause");
}
标签:std printf strcmp als 默认 sizeof 函数返回值 应该 项目
原文地址:https://www.cnblogs.com/2dx3906/p/13166930.html