C++基础知识(Ⅲ)

前言

参考资料:http://c.biancheng.net/cplus/

一.友元

1.友元函数

C++类中有三种属性的成员,其中private属性的成员是不能被非该类的成员函数访问。但我们可以借助友元,使其他类的成员函数或全局函数访问该类的私有成员private。
将不属于当前类的函数前面加上关键字’friend’即可变为该类的友元函数。

class Student1{
public:
    //成员函数
    void information1()(Student2* pstudents)
    //将外部函数声明为友元函数
    friend void information0(Student1* pstudents);
private:
    char* m_name;
    int m_age;

//全局友元函数定义时不需要加friend,调用时直接用全局函数的方式调用即可
void information0(Student1* pstudents){
    cout << "姓名" << pstudents->n_name << "\n年龄" << pstudents->n_age << endl;
};

class Student2{
private:
    char* m_name;
    int m_age;
public:
    //将Student1类中的成员函数information1()声明为友元函数
    friend Student1::information1(Student2* pstudents);
};

//定义友元函数,由于属于类Student1,因此传递隐藏参数this指针
void Student1::information1(Student2* pstudents){
    cout << "姓名1" << n_name << "\n年龄1" << n_age << endl;
    cout << "姓名2" << pstudents->n_name << "\n年龄2" << pstudents->n_age << endl;
}

注意,最好将所有类都放在头文件中声明,以免报错。

2.友元类

可以直接将一个类声明为另一个类的友元类。例如将类 B 声明为类 A 的友元类,那么类 B 中的所有成员函数都是类 A 的友元函数,可以访问类 A 的所有成员,包括 public、protected、private 属性的。

class Student2{
private:
    char* m_name;
    int m_age;
public:
    //将Student1类声明为Student2类的友元类。
    friend class Student1;
};

注意:友元的关系是单向的,即类B是类A的友元类,不等于类A是类B的友元类。

二.字符串结构

1.char型

char型字符串的构造需要比装载的字符多一位,因为结尾有结束标志’\0’。

//hi只有两个字符,但构建的字符数组需要3位。
char a[3] = "hi";

2.string型

string字符串是一个大神器。string定义的字符串结尾没有结束标志’\0’。

(1)string输入输出

#include<string>
using namespace std;

int main(){
    string s = "hello world";
    string s1 = s;
    string s2(8, 'o');
    int len = s.length();
    // length()返回的是字符串真实长度11而不是12。
    cout << len << endl;
}

string字符串可直接使用cin和cout输入输出,但注意在使用键盘输入时,中间不能有空格,否则cin>>遇到空格就会认为输入结束,导致真正读取到的输入不完整。

string字符串可以与另一string字符串或char型字符串拼接。
以下代码来源:http://c.biancheng.net/view/2236.html

int main(){
    string s1 = "first";
    string s2 = "second";
    char *s3 = "third";
    char s4[] = "fourth";
    char ch = '@';
    string s5 = s1 + s2;
    string s6 = s1 + s3;
    string s7 = s1 + s4;
    string s8 = s1 + ch;
    
    cout<<s5<<endl<<s6<<endl<<s7<<endl<<s8<<endl;
    return 0;
}

(2)string的增删改查

注意pos和len的越界问题。
1.使用string1.insert(pos, string2)在string1字符串的指定位置(pos)插入另一个字符串(string2),修改string1。

string s1, s2;
s1 = "gogogo";
s2 = "lag";
s1.insert(2, s2);
cout << s1 << endl;

2.使用string1.erase(pos, len)在string1字符串的指定位置(pos)删除子字符串(长度为len,不说明长度则表示pos以后的全部删除),修改string1。

string s1;
s1 = "gogogo";
s1.erase(2,2);
cout << s1 << endl;

3.使用string1.substr(pos, len)在string1字符串的指定位置提取子字符串(长度为len),不修改string1。

string s1 = "gogogo";
string s2;
s2 = s1.substr(2, 4);
cout << "s1:" << s1 << "'\n's2:" << s2 <<endl;

4.提供三种用于字符串查找
1)find(string1, pos)函数,从pos位置开始查找,返回子字符串第一次出现在字符串中的起始下标。

string s1 = "hcnb";
string s2 = "nb";
int index_nb;
index_nb = s1.find(s2, 0);
cout << index_nb << endl;

2)rfind()函数,和find类似,区别是rfind函数从初始位置查找到pos位置,同样返回起始下标。

string s1 = "hcnb";
string s2 = "nb";
int index_nb1 = s1.rfind(s2, 1);
int index_nb2 = s1.rfind(s2, 2);
cout << index_nb1 << '\n' << index_nb2 << endl;

输出结果显示,index_nb1返回-1,说明没查找到;index_nb2返回2,说明查找到,且子字符串的初始位置在index=2处。

3)find_first_of()函数,查找子字符串和字符串共同具有的字符在字符串中首次出现的位置。

string s1 = "hcgogogo";
string s2 = "go";
int index = s1.find_first_of(s2);
cout << index << endl;

三.函数中的参数传递

C++的参数传递机制有三种:值传递、指针传递、引用传递

1.值传递

实参的值被复制到对应的形参所标识的对象中去,成为形参的初始值。
函数中语句对形参的操作与实参对象无关

2.指针传递

函数中的形参是指针类型,调用函数时将实参把对象的地址值赋给形参标识的指针变量。
被调用函数可以通过形参指针间接访问实参地址所指对象。可用const约束形参指针,赖避免被调用函数对实参所指对象进行修改。

3.引用传递

函数中形参是引用类型,实参是对象名, 形参作为引用绑定在实参标识的对象上,对形参的操作就是对实参对象的操作
和指针传递一样,为避免被调用函数对实参对象的修改,可以使用 const限定引用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值