友元
友元是一种定义在类外部的普通函数或类,需要在类中声明,基本格式为friend 函数原型,友元不是成员函数,但它可以访问类中的私有成员
存在形式
- 友元普通函数
- 友元成员函数
- 友元类
特点
- 单向
- 不具有传递性
- 不能被继承。
运算符重载
运算符重载,就是对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型。
重载规则
- 操作符重载必须具有一个类类型或枚举类型的操作数
- 优先级和结合性是固定的
- 不再具备短路求值特性
- 不能臆造并重载一个并不存在的运算符
- 并非所有的运算符都能重载
不能重载的运算符
- 成员运算符 .
- 成员指针运算符 .*
- 域运算符 ::
- 长度运算符 sizeof [sizeof a 也可这样调用]
- 条件运算符 ?:
重载形式
- 普通函数
- 友元函数
- 成员函数(一般很少使用)
由于现阶段时间不够,这些运算符的重载就不一一实现了,以下代码是我自己用重载方式实现的一个string类,算是一个总结
string_operator.h
#pragma once
#include <cstring>
#include <iostream>
using namespace std;
class String
{
public:
String();
String(const char *);
String(const String &);
~String();
void print()
{
cout << _str << endl;
}
String &operator=(const String& s);
String &operator=(const char *);
String &operator+=(const String&);
String &operator+=(const char *);
char *operator[](std::size_t index);
const char &operator[](std::size_t index) const;
std::size_t size() const;
const char *c_str() const;
friend bool operator==(const String &, const String &);
friend bool operator!=(const String &, const String &);
friend bool operator<(const String &, const String &);
friend bool operator>(const String &, const String &);
friend bool operator<=(const String &, const String &);
friend bool operator>=(const String &, const String &);
friend std::ostream &operator<<(std::ostream &os, const String &s);
friend std::istream &operator>>(std::istream &is, const String &s);
private:
char *_str;
};
string_operator.cc
#include "string_operator.h"
String::String()//默认构造函数
:_str(new char[1]())
{
}
String::String(const char *str)
:_str(new char[strlen(str)+1]())
{
strcpy(_str, str);
}
String::String(const String& s)
:_str(new char[strlen(s._str)+1]())
{
strcpy(_str, s._str);
}
String::~String()
{
if(_str)
delete []_str;
}
String & String::operator=(const String& s)
{
if(this != &s)
{
free(_str);
this->_str = new char[strlen(s._str)+1]();
strcpy(_str, s._str);
}
return *this;
}
String &String::operator=(const char *s)
{
bzero(_str, sizeof(_str));
strcpy(_str, s);
return *this;
}
String &String::operator+=(const String& s)
{
String tmp = _str;
_str = new char[strlen(_str)+strlen(s._str)+1]();
strcpy(_str,tmp._str);
strcat(_str,s._str);
return *this;
}
String &String::operator+=(const char *s)
{
String tmp = _str;
_str = new char[strlen(_str)+strlen(s)+1]();
strcpy(_str,tmp._str);
strcat(_str,s);
return *this;
}
char *String::operator[](std::size_t index)
{
if(index >= 0 && index < strlen(_str))
return _str + index;
}
const char &String::operator[](std::size_t index) const//此函数只能被const对象调用
{
if(index >= 0 && index < strlen(_str))
return _str[index];
}
std::size_t String::size() const
{
return strlen(_str);
}
const char *String::c_str() const
{
return _str;
}
bool operator==(const String &lhs, const String &rhs)
{
if(!strcmp(lhs._str, rhs._str))
return true;
return false;
}
bool operator!=(const String &lhs, const String &rhs)
{
return !(lhs == rhs);
}
bool operator<(const String &lhs, const String &rhs)
{
return strcmp(lhs._str, rhs._str) < 0;
}
bool operator>(const String &lhs, const String &rhs)
{
return strcmp(lhs._str, rhs._str) > 0;
}
bool operator<=(const String &lhs, const String &rhs)
{
return strcmp(lhs._str, rhs._str) <= 0;
}
bool operator>=(const String &lhs, const String &rhs)
{
return strcmp(lhs._str, rhs._str) >= 0;
}
std::ostream &operator<<(std::ostream &os, const String &s)
{
os << s._str;
return os;
}
std::istream &operator>>(std::istream &is, const String &s)
{
is >> s._str;
return is;
}
String operator+(const String &lhs, const String &rhs)
{
String tmp;
tmp += lhs;
tmp += rhs;
return tmp;
}
String operator+(const String &lhs, const char *str)
{
String tmp;
tmp += lhs;
tmp += str;
return tmp;
}
String operator+(const char *str, const String &rhs)
{
String tmp;
tmp += str;
tmp += rhs;
return tmp;
}
void test()
{
String s1;
String s2("This is a test string.");
String s3(s2);
String s4 = s3;
cout << s2 << endl << s3 << endl << s4 << endl;
const String s5 = s3;
cout << *s2[3] << endl;
cout << s5[3] << endl;
cout << s5+s3 << endl;
cout << s5+" hello,world" << endl;
cout << (s5>s3) << endl;
cout << (s5<=s3) << endl;
cout << (s5==s3) << endl;
cout << (s5!=s3) << endl;
String s6;
cin >> s6;
cout << (s6 + s5) << endl;
s6 += s5;
cout << s6 << endl;
cout << "hello,world " + s6 << endl;
}
int main(int argc, char *argv[])
{
test();
return 0;
}