1、友元
(1)友元函数:如果一个函数是类A的友元函数,那么改函数可以通过对象使用A中的所有成员(破坏了类的封装性)
使用方法:在类中声明函数,在函数名前面添加friend.
注意:
友元的声明不受访问控制符的限制,可以在类中的任意位置声明,一般放在类的最开始位置,便于查找。
友元函数是“友”,不属于类的内部成员函数,是外部函数,因此没有隐藏的this指针
(2)友元类:如果类A是类B的友元类,那么类A中所有的函数都是类B的友元函数。
2、运算符重载
1、函数格式
(1)函数名:operator加上运算符
(2)函数参数:从左到右,参与运算的运算符。
(3)函数的返回值:根据需要填写
2、运算符重载可以放在外部实现,需要友元声明。
3、运算符在类内部实现的方法:去掉左操作数,由this作为左操作数
4、运算符在类内部的限制:左操作数不能改变的。
5、注意:
(1)不能改变运算符的优先级
(2)不能改变运算符的操作个数
(3)不能自创运算符
(4)同一种运算,内部和外部只能存在一个
不能重载的运算符:
::
?:
.
.*
sizeof
只能放在类中实现的
“=”
()
[ ]
6、实现字符串的运算:
mysring.h文件
#ifndef MYSTRING_H
#define MYSTRING_H
#include <iostream>
class MyString
{
// 重载 << 操作符
friend std::ostream& operator<<(std::ostream &out, MyString &str);
// 重载 >> 操作符
friend std::istream& operator>>(std::istream& in, MyString &str);
public:
MyString(); // 无参构造
MyString(const char *s); // 有参构造
MyString(int len, char data = 0); // 有参构造
MyString(const MyString &s); // 拷贝构造
~MyString(); // 析构函数
// 重载=、[]操作符
public:
MyString& operator=(const char *s); // 普通字符串赋值
MyString& operator=(const MyString &s); // 类对象之间赋值
char & operator[](int index);
// 重载 + 运算符
public:
MyString operator+(const char *str);
MyString operator+(const MyString &s);
MyString& operator+=(const char *str);
MyString& operator+=(const MyString &s);
// 重载 == !=
public:
bool operator==(const char *str) const;
bool operator==(const MyString &str) const;
bool operator!=(const char *str) const;
bool operator!=(const MyString &str) const;
// 重载 < >
public:
bool operator>(const char *str) const;
bool operator>(const MyString &str) const;
bool operator<(const char *str) const;
bool operator<(const MyString &str) const;
public:
const char *c_str()
{
return m_p;
}
char *c_str2()
{
return m_p;
}
int leng()
{
return m_len;
}
private:
int m_len; // 字符串长度
char *m_p; // 字符串数据
};
#endif // MYSTRING_H
mystring.c文件
#include "mystring.h"
#include <cstring>
#include <iostream>
MyString::MyString()
{
m_p = nullptr;
}
MyString::MyString(const char *s)
{
if(s == nullptr)
{
m_p = nullptr;
m_len = 0;
}
else
{
m_len = strlen(s);
m_p = new char[m_len+1];
strcpy(m_p,s);
}
}
MyString::MyString(int len, char data)
{
if(len == 0)
{
m_p = nullptr;
m_len = 0;
}
else
{
m_len = len;
m_p = new char[len];
for(int i = 0;i<len;i++)
{
m_p[i] = data;
}
}
}
MyString::MyString(const MyString &s)
{
m_len = s.m_len;
m_p = new char[m_len+1];
strcpy(m_p,s.m_p);
}
MyString& MyString::operator=(const char *s)
{
m_len = strlen(s);
m_p = new char[m_len+1];
strcpy(m_p,s);
return *this;
}
MyString& MyString::operator=(const MyString &s)
{
if(this != &s)
{
m_len = s.m_len;
m_p = new char[m_len+1];
strcpy(m_p,s.m_p);
}
return *this;
}
MyString MyString::operator+(const char *str)
{
int len = m_len + strlen(str);
MyString tmp(len);
strcpy(tmp.m_p,m_p);
strcat(tmp.m_p,str);
return tmp;
}
MyString MyString::operator+(const MyString &s)
{
int len = m_len + s.m_len;
MyString tmp(len);
strcpy(tmp.m_p,m_p);
strcat(tmp.m_p,s.m_p);
return tmp;
}
MyString& MyString::operator+=(const char *str)
{
// *this = *this + str;
m_len = m_len + strlen(str);
char *tmp = m_p;
m_p = new char[m_len+1];
strcpy(m_p,tmp);
strcat(m_p,str);
delete[] tmp;
return *this;
}
MyString& MyString::operator+=(const MyString &s)
{
m_len = m_len + s.m_len;
char *tmp = m_p;
m_p = new char[m_len+1];
strcpy(m_p,tmp);
strcat(m_p,s.m_p);
delete[] tmp;
return *this;
}
char & MyString::operator[](int index)
{
return m_p[index];
}
bool MyString::operator==(const char *str) const
{
return (strcmp(m_p,str) == 0);
}
bool MyString::operator==(const MyString &str) const
{
return (strcmp(m_p,str.m_p) == 0);
}
bool MyString::operator!=(const char *str) const
{
return (strcmp(m_p,str) != 0);
}
bool MyString::operator!=(const MyString &str) const
{
return (strcmp(m_p,str.m_p) != 0);
}
bool MyString::operator>(const char *str) const
{
return (strcmp(m_p,str) > 0);
}
bool MyString::operator>(const MyString &str) const
{
return (strcmp(m_p,str.m_p) > 0);
}
bool MyString::operator<(const char *str) const
{
return (strcmp(m_p,str) < 0);
}
bool MyString::operator<(const MyString &str) const
{
return (strcmp(m_p,str.m_p) > 0);
}
MyString::~MyString()
{
if(m_p != nullptr)
delete[] m_p;
m_p = nullptr;
m_len = 0;
}
main.c文件
#include <iostream>
#include "mystring.h"
using namespace std;
std::ostream& operator<<(std::ostream &out, MyString &str)
{
out<<"打印内容:"<<str.m_p;
return out;
}
std::istream& operator>>(std::istream& in, MyString &str)
{
in >> str.m_p;
return in;
}
int main1()
{
MyString str = "hello";
char * p = str.c_str2();
printf ("%s\n", str.c_str());
return 0;
}
int main2()
{
MyString str; // 空字符串
MyString str1 = "hello world"; // 用一个字串去初始化类对象
MyString str2 = NULL; // 空字符串
MyString str3 = str1; // 用一个字符串对象初始化当前对象
MyString str4(10, 'a'); // 长度为10,每一个元素都是'a'
MyString str5(20);
printf ("%s\n", str3.c_str());
return 0;
}
int main3()
{
MyString str1 = "hello world"; // 用一个字串去初始化类对象
// <<
// ostream & operator<<(ostream &out, MyString &str)
std::cout << str1 << std::endl;
MyString str2(4);
// >>
// istream& operator>>(istream& in, MyString &str);
std::cout << "请输入字符串:" ;
std::cin >> str2;
std::cout << str2 << std::endl;
return 0;
}
int main4()
{
MyString str1;
// MyString & operator(MyString &str, const char *s)
str1 = "hello"; // 重载赋值操作符 =
//str1 = NULL;
std::cout << str1 << std::endl;
MyString str2;
str2 = str1;
std::cout << str2 << std::endl;
str2 = str2;
return 0;
}
int main5()
{
MyString str1 = "hello ";
MyString str2 = "world";
MyString str3;
str3 = str1 + "world";
str3 = str1 + str1;
str1 += "world";
str1 += str1;
std::cout << str3 << std::endl;
std::cout << str1 << std::endl;
return 0;
}
int main6()
{
MyString str1 = "hello";
std::cout << str1[3] << std::endl;
str1[3] = 'w';
std::cout << str1 << std::endl;
return 0;
}
int main7()
{
MyString str1 = "helo";
MyString str2 = "world";
if (str1 == "hello")
{
printf ("str1 == hello\n");
}
else
{
printf ("str1 != hello\n");
}
if (str1 == str2)
{
printf ("str1 == str2\n");
}
else
{
printf ("str1 != str2\n");
}
return 0;
}
int main()
{
MyString str1 = "chelo";
MyString str2 = "world";
if (str1 > "bhello")
{
printf ("str1 > hello\n");
}
if (str1 > str2)
{
printf ("str1 > str2\n");
}
else
{
printf ("str1 < str2\n");
}
return 0;
}