
#include<iostream>
using namespace std;
//友元类的声明所在的类,一定要在友元类的上面,或是声明在所在类的上方
//因为友元类访问私有需要用到已定义的类
//而编译是从上至下进行的
//造成了编译错误
//就像客人突然到访,主人没有做好准备。
class A
{
public:
//友元类申明
friend class B;
class C
{
public:
void fun(A& aa)
{
std::cout << "inner class" << std::endl;
std::cout << aa.a << " ";
std::cout << std::endl;
}
};
private:
int a = 11;
};
//友元类
struct B
{
void func(A& aa)
{
std::cout << "friend class or friend function" << std::endl;
std::cout << aa.a;
std::cout << std::endl;
}
};
int main()
{
A aa;
B b;
b.func(aa);
return 0;
}class string
{
private:
//在类和对象中的变量前加上一个下划线(_),代表这是变量,
//让程序可读性更强一些。
//加上一些缺省参数,减少错误的访问。
char* _str = nullptr;
size_t _size = 0;
size_t _capacity = 0;
}//定义一定是在类中定义或是在类中声明类外定义
//这里把它单独拿出来为了好看一些。
string(const char* str = "")
//这里的缺省值空字符串代表的就是字符末尾'\0'
//毕竟C语言是用'\0'来作为字符串末尾的
//C++要兼容C语言,自然要对C语言内容有所保留。
{
size_t len = strlen(s);
_str = new char[len + 1];
strcpy(_str,s);
_size = _capacity = len;
}string(const string& s)
{
size_t len = strlen(s._str);
//_size和_capacity不将'\0'计算在内
//毕竟strlen()也不计算'\0'。
//计算有效字符。
//所以len加一是多一个空间存放'\0'
_str = new char[len + 1];
strcpy(_str,s._str);
_size = _capacity = len;
}~string()
{
//delete后加上[]是因为_str是一个数组,不是一个变量
//我们定义数组时也会加[]
delete[] _str;
_size = _capacity = 0;
}void reserve(size_t n)
{
if (n > _capacity)
{
char* tmp = new char[n + 1];
strcpy(tmp,_str);
_capacity = n;
delete[] _str;
_str = tmp;
}
} const char* string:: c_str()const
{
return _str;
}// 在pos位置上插入字符c/字符串str,并返回该字符的位置
string& insert(size_t pos, char c)
{
assert(pos < _size);
_str[pos] = c;
return (*this);
}
string& insert(size_t pos, const char* str)
{
size_t len = strlen(str);
if (_size + len > _capacity)
{
reserve(_size + len > 2 * _capacity ? _size + len : _capacity);
}
for (int i = 0; i < len; i++)
{
_str[pos + i] = str[i];
}
_size += len;
_str[_size] = '\0';
return (*this);
}
string& erase(size_t pos, size_t len)
{
for (int i = pos + len; i <= _size; i++)
{
_str[i - len] = _str[i];
}
_size -= len;
return (*this);
}size_t size()
{
return _size;
}
size_t capacity()
{
return _capacity;
}string& operator+=(char c)
{
if (_size == _capacity)
{
reserve(2 * _capacity);
}
_str[_size] = c;
++_size;
return (*this);
}
string& operator+=(const char* str)
{
(*this).insert(_size,str);
return (*this);
}
char& operator[](size_t index)
{
assert(index < _size);
return _str[index];
}size_t find(char c, size_t pos) const
{
for (int i = pos; i < _size; i++)
{
if (_str[i] == c)
{
return i;
}
}
return npos;
}
// 返回子串s在string中第一次出现的位置
size_t find(const char* s, size_t pos) const
{
char* tmp = strstr(_str + pos, s);
return tmp - _str;
}
void clear()
{
_str[0] = '\0';
_size = 0;
}std::ostream& operator << (std::ostream& _cout, const word::string& s)
{
//范围for()通过类中的begin()和end()函数的返回值访问
//将s中的字符插入在流中
for (auto& ch : s)
{
_cout << ch;
}
return _cout;
}
std::istream& operator >> (std::istream& _cin, word::string& s)
{
//在提取之前先清除一下s中的所有字符
//用一个字符数组充当缓冲区,减少扩容次数,增加效率
s.clear();
const int N = 255;
char buf[N + 1] = { 0 };
int i = 0;
char ch = '\0';
//因为输入输出默认用空格和换行做分隔符。
while (ch != ' ' && ch != '\n')
{
// get()函数一个字符一个字符地去读
ch = _cin.get();
buf[i++] = ch;
if (i == N - 1)
{
buf[i] = '\0';
i = 0;
s += buf;
}
}
if (i > 0)
{
buf[i] = '\0';
s += buf;
}
return _cin;
}typedef char* iterator;
typedef const char* const_iterator;
iterator begin()
{
//数组名就是是首元素的地址。
return _str;
}
iterator end()
{
return _str + _size;
}
const_iterator begin() const
{
return _str;
}
const_iterator end() const
{
return _str + _size;
}