字符串数组|char *转换为unsigned int|友元

本文介绍了C语言中字符串数组的应用及如何通过友元函数和友元类访问类的私有成员,同时展示了如何使用strtoul函数进行字符串到整数的转换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


实现功能:

因为char *一定程度上相当于string

又加上了数组定义,就相当于一个字符串数组了。


调用的时直接array[i]即可!


用到的函数是:

strtoul(待转换的字符串,endptr,10进制);


采用类的机制后实现了数据的隐藏与封装,类的数据成员一般定义为私有成员,成员函数一般定义为公有的,依此提供类与外界间的通信接口。但是,有时需要定义 一些函数,这些函数不是类的一部分,但又需要频繁地访问类的数据成员,这时可以将这些函数定义为该函数的友元函数。除了友元函数外,还有友元类,两者统称 为友元。友元的作用是提高了程序的运行效率(即减少了类型检查和安全性检查等都需要时间开销),但它破坏了类的封装性和隐藏性 ,使得非成员函数可以访问类 的私有成员。

友元函数

      友元函数是可以直接访问类的私有成员 的非成员函数。它是定义在类外的普通函数,它不属于任何类,但需要在类的定义中加以声明,声明时只需在友元的名称前加上关键字friend,其格式如下:
      friend  类型 函数名(形式参数);

      友元函数的声明可以放在类的私有部分,也可以放在公有部分,它们是没有区别的,都说明是该类的一个友元函数。
      一个函数可以是多个类的友元函数,只需要在各个类中分别声明。
      友元函数的调用与一般函数的调用方式和原理一致。

友元类
      友元类的所有成员函数都是另一个类的友元函数,都可以访问另一个类中的隐藏信息(包括私有成员和保护成员)。       
      当希望一个类可以存取另一个类的私有成员时,可以将该类声明为另一类的友元类。定义友元类的语句格式如下:
      friend class 类名;
      其中:friend和class是关键字,类名必须是程序中的一个已定义过的类。

      例如,以下语句说明类B是类A的友元类:
      class A
      {
             …
      public:
             friend class B;
             …
      };
      经过以上说明后,类B的所有成员函数都是类A的友元函数,能存取类A的私有成员和保护成员。

      使用友元类时注意:
            (1)
友元关系不能被继承。
            (2) 友元关系是单向的,不具有交换性。 若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明。
            (3) 友元关系不具有传递性。 若类B是类A的友元,类C是B的友元,类C不一定是类A的友元,同样要看类中是否有相应的申明

 

 


If you have any questions or ideas ,please feel free to contact me : )

thx.^^


QQ: 1623213673

MAIL: codingkid@qq.com

#include<iostream> class Role { public: int hp; int mp; }; class hstring { unsigned short usmlen;//字符串的内存长度 unsigned short uslen;//字符串的长度 char* cstr;//字符串的内容 unsigned short GetLength(const char* str)const; // 4. 获取字符串长度 void CopyStrs(char* dest, const char* source); // 5. 字符串复制函数(用于赋值/构造) public: hstring(); // 1. 默认构造函数 char* c_str() { return cstr; } //7. 输出 str 的字符串内容 hstring(const char* str); //利用c字符串来构造hstring // 2. 用 C 字符串构造 hstring hstring(const hstring& str) ;//利用hstring来构造hstring //3. 拷贝构造函数 hstring & operator=(const hstring& str);//赋值运算符 // 6. 赋值运算符重载(hstring = hstring){只有这个是关于赋值重载的调用,其他5点是用函数的方式完成要求} hstring& operator=(const char* str); //hstring& operator=(const long long& value);//实现long long类型作业 //************************************重载位移运算符******************** hstring& operator<<(const hstring& str); hstring& operator+(const hstring& str); }; // 1. 默认构造函数 hstring::hstring() { usmlen = 0x32; uslen = 0; cstr = new char[usmlen]; } // 2. 用 C 字符串构造 hstring hstring::hstring(const char* str) :hstring() { //cstr = (char*)str; CopyStrs(cstr, str); } // 3. 拷贝构造函数 hstring::hstring(const hstring& str) :hstring() { CopyStrs(cstr, str.cstr); } // 4. 获取字符串长度 unsigned short hstring::GetLength(const char* str) const { unsigned short len = 0; for (; str[len++];); return len; } // 5. 字符串复制函数(用于赋值/构造) void hstring::CopyStrs(char* dest, const char* source) { unsigned short len = GetLength(source); if (len > usmlen) { //内存泄露的问题 delete[] cstr; // 先释放旧内存 cstr = new char[len];//重新分配内存 usmlen = len;//修正内存的长度 } memcpy(cstr, source, len); uslen = len;//字符串长度修正 } //6. 赋值运算符重载(hstring = hstring) hstring& hstring::operator=(const hstring& str) { CopyStrs(cstr, str.cstr); return *this; } //8.被注释的赋值运算, 尝试将 C 字符串赋值给 hstring 对象 hstring& hstring::operator=(const char* str) { CopyStrs(cstr, str); return *this; } //************************************重载位移运算符******************** hstring& hstring::operator<<(const hstring& Tstr) { unsigned short slen = GetLength(Tstr.cstr); //123 Ox0 slen = uslen + slen - 1; if (slen > usmlen){ delete[]cstr; //删除内存 cstr = new char[slen]; //重新分配内存 usmlen = slen;//修正内存的长度 } memcpy(cstr + uslen -1,Tstr.cstr, slen - uslen + 1); uslen = slen;//字符串长度修正 return *this; } hstring& hstring::operator+(const hstring& str) { return *this << str; } int main() { Role x, y, z; // 1. 定义三个 Role 对象 x, y, z x.hp = 100; x.mp = 200; // 2. 给 x 的成员赋值 z = y = x; // 3. 连续赋值:y = x; z = y;// 注意:这里使用的是默认的赋值操作符(浅拷贝) std::cout << y.hp << "/////////" << y.mp<<std::endl; // 4. 输出 y 的 hp 和 mp char strA[] = "aaaaaaabbbbbbbbcccccc"; // 5. 定义一个 C 风格字符串 hstring str{ strA }; // 6. 使用 C 字符串构造 hstring 对象 str // 调用:hstring(const char* str) 2. 用 C 字符串构造 hstring //hstring str = strA ; // 注释掉的写法:等价于上面那行 // 实际上也调用 hstring(const char*) 2. 用 C 字符串构造 hstring hstring str1{ str }; // 7. 使用拷贝构造函数构造 str1 // 调用:hstring(const hstring& str) 3. 拷贝构造函数 hstring str2{ "hello!" }; // 8. 使用字符串字面量构造 str2 // 调用:hstring(const char* str) 2. 用 C 字符串构造 hstring std::cout << str.c_str(); // 9. 输出 str 的字符串内容 // 调用:char* c_str() { return cstr; } 7. 输出 str 的字符串内容 std::cout << std::endl; // 10. 输出换行 std::cout << str1.c_str()<<std::endl; // 11. 输出 str1 的字符串内容 // 调用:char* c_str() 7. 输出 str 的字符串内容 str1 = str2; // 12. 调用赋值运算符:str1 = str2 // 调用:hstring& operator=(const hstring&) // 6. 赋值运算符重载(hstring = hstring) hstring str3 = {}; str3 = "你好袁鑫"; // 13. 尝试将 C 字符串赋值给 hstring 对象 // 当前代码中 operator=(const char*) 被注释了,所以这行会报错 // 如果你实现了 operator=(const char*),就会调用它 //8.被注释的赋值运算, 尝试将 C 字符串赋值给 hstring 对象 std::cout << str3.c_str()<<std::endl; // 14. 输出 str1 的内容 printf("\r\n"); std::cout << "**********************************************" << std::endl; //**************************重载位移运算符*********************** hstring Tstr{ "大家好啊!" }; hstring Tstr1{"@@@/"}; Tstr << "123"<<"158746"<<"加油努力,冲冲冲"; std::cout << Tstr.c_str(); std::cout << Tstr1.c_str(); 只关注与<<运算符和+运算符的地方 我有两个问题,第一个是为什么这里+运算符 return *this << str;这样写是运用了<<重载运算符的内容,还有就是为什么 std::cout << Tstr1.c_str();这里是 Tstr1.c_str()
最新发布
07-31
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值