分享

【编程语言】你对C 关键字了解多少?

 zeroxer2008 2022-01-13

大家好,我是行码棋!

c++面向对象有很多有意思的知识点,今天我带大家来了解一下c++的关键字的相关知识,希望大家能够有所收获。

特定关键词的用法

1.const限定词

1.1.常对象

将对象限定为const对象,即为常对象。

特性:

1.常对象在生存期它的「所有数据成员都不可以改变」

2.常对象在定义时就「必须进行初始化」,且「不能被更新」

3.如果要调用常对象中的成员函数,「成员函数必须为常成员函数」,这样才能成功调用,否则就会出错

const修饰形式(两种均可)

1.const 类名 对象名([参数列表])

2.类名 const 对象名([参数列表])

代码演示:假设已定义一个Time类,有年月日三个成员变量

Time const t1(2021,6,9);//定义t1常对象
//或const Time t1(2021,6,9);

注意:

如果一定要修改某个常对象的成员变量的值,可以将公式声明为mutable

mutable int count;

这样就可以用声明为const的「常成员函数」来修改它的值。

1.2.常成员函数

常对象只能调用常成员函数,这样保证常对象的数据成员不能修改。

特性:

1.函数实现时需要带上const关键字 2.常成员函数「不能更新」对象的「数据成员」,也「不能调用非常成员函数」。 3.常成员函数只能调用常成员函数,常成员函数「也能被普通对象调用」(这个要注意一下,容易错)。

调用形式:

//在Time对象中对gethour方法定义为const成员函数
int Time::gethour() const
{

}

const关键字可以被用于参与对重载函数的区分。

  • const成员函数可以进行非const版本的重载。
  • 编译器可以根据情况选择相应的重载函数。
  • 如果对象是const,使用const版本的重载函数,如果是非const,使用非const版本的重载函数。

注意:

析构函数和构造函数「不能」进行const声明。 因为构造函数「必须能够修改对象」,析构函数需要对对象的「内存进行回收」

1.3.常数据成员

  • 使用const声明的数据成员为常数据成员。
  • 对于常数据成员,「任何函数」都不能对它进行赋值,也「不能通过构造函数赋值」的方法进行赋值,只能通过初始化器(成员初始化列表)进行赋值

初始化器进行赋值:

class Time
{

private:
 const int hour;
 const int second;
 const int minute;
};
Time::Time(int h,int s,int m)
 :hour(h),second(s),minute(m)//成员初始化列表(初始化器)
 { }//注意花括号不能省略

1.4.对象常引用

对象的引用就是该对象的别名,对象名和引用名「都指向相同的内存单元。」可以认为对象名和引用名的作用相同,属于同一个东西,就像一个人有两个名字一样。

「使用场景:」希望通过引用名「只能调用对象中的公有成员」,而不能修改它们。(只有使用权,没有修改权)

声明形式: const 类名 &引用名  = 对象名;

Time t1;
const Time &t2 = t1;//t1和t2指向同一段内存  

偷来一张图,嘿嘿,总结一下~图片

2.组合类

定义:在一个类的数据成员中出现一个或多个类的对象,那这个类就叫做组合类。

「组合类构造函数定义的一般形式为:」

类名::类名(形参表):内嵌对象1(形参表), 内嵌对象2(形参表),…
{
  //类的初始化
}

其中,“内嵌对象1(形参表), 内嵌对象2(形参表),…”为「初始化列表」(初始化器),用来完成对内嵌对象的初始化。

「注意:」如果有多个内嵌对象,需要按它们在类中的声明顺序来调用他们对应的构造函数。最后在执行本类的构造函数。

#include<bits/stdc++.h>
using namespace std;

class Location
{

private:
    string loc;
public:
    Location(string s):loc(s){}
};
class Time
{

private:
    int hour;
    int minute;
    int second;
    Location l;
public:
    Time(int h,int m,int se,string s):l(s)
    {
        hour = h;
        minute = m;
        second = se;
    }
};
int main()
{
    Time t(12,12,12,'China');
    return 0;
}

3.友元

3.1 介绍:

在一个类中,使用关键字friend将别的模块(一般函数、其它类的成员函数或其它类)声明为本类的友元,这样类中本来隐藏的信息(私有和保护成员)就可以被友元访问。

可以说是friend为访问本类开了一个特殊的权限,本来内部的私有成员和保护成员不可以被外界访问,但是声明为friend的函数「在外部可以访问到本类的私有成员。」

友元提供了不同类或对象的成员函数之间、类的成员函数与一般函数之间进行数据共享的机制。

注意: 友元并不是类的成员。

3.2 友元函数

1、在类体内说明,在函数的类型说明符前加关键字friend;

2、在类体外定义,定义格式与普通函数相同;

3、友元函数是「非成员函数」,在调用上与普通函数相同;

4、友元函数可以「直接访问该类中的私有成员。」

下面以重载输入输出运算符为例来说明:

//实现对复数类的输入输出
#include<iostream>
using namespace std;
class CComplex
{

private:
    double real,imag;
public:
    CComplex(double r=0,double i=0):real(r),imag(i){}
    //内部声明,下面是友元,非成员函数
    friend istream& operator >> (istream& in,CComplex &c);
    friend ostream& operator << (ostream& out,CComplex c);
};

//外部实现
istream& operator >> (istream& in,CComplex &c)
{
    cout<<'请输入实部和虚部\n';
    in >> c.real >> c.imag;
    return in;
}
ostream& operator << (ostream& out,CComplex c)
{
    if(c.imag<0)//虚部小于0
    {
        out<<c.real<<c.imag<<'i\n';
        return out;
    }
    else if(c.imag==0)//虚部等于0
    {
        out<<c.real<<'\n';
        return out;
    }
    else //虚部大于0
    {
        out<<c.real<<'+'<<c.imag<<'i\n';
        return out;
    }
}
int main()
{
 CComplex cc;
    cin>>cc;
    cout<<cc;
 return 0;
}

3.3 友元类

当说明一个类为另一个类的友元时,友元类中的「所有成员函数」都是另一个类的友元函数。

也就是说友元类中的所有成员函数都可访问该类的私有变量。

声明形式:

friend class 类名;

注意:

1.友元关系不能传递。B类是A类的友元,C类是B类的友元,但C类并不是A类的友元。

2.友元关系是单向的。若B类是A类的友元,B类成员函数可以访问A类的私有变量,但是反过来A类成员函数并不能访问B类的私有变量。

4.this指针

this指针表示正在调用函数对象的地址。

什么意思呢?

当对象s 调用 s.set(2,15,1998) 时,成员函数除了接收传递的3个参数外,还接收到正在调用成员函数的对象s 的地址,这个地址放入隐含的形参this 指针中。

等同于执行 「this=&s;」 语句。

所以对成员函数内数据成员的访问都隐含地加上了this 指针。

因此, month=m; 等价于  this->month=m; 或 s.month=m;

「this指针存的就是目前本对象的地址。」

this指针的一个用处: 当成员函数中出现和成员变量同名的变量时,系统无法区分这些变量。使用this指针可以指向本类的成员变量,而另外一个变量就可以使用

Time(int hour,int minute,int second)
{
    this->hour = hour;//把参数hour的值赋给类中的hour私有变量
    this->minute = minute;
    this->second = second;
}

以下是完整的代码:

#include<iostream>
using namespace std;
class Time
{

private:
    int hour;
    int minute;
    int second;
public:
    Time(int hour,int minute,int second)
    {
        this->hour = hour;
        this->minute = minute;
        this->second = second;
    }
    void print()
    
{
    //下面两种方式是一样的,都代表本类的成员变量
        // cout<<hour<<':'<<minute<<':'<<second<<'\n';
        cout<<this->hour<<':'<<this->minute<<':'<<this->second<<'\n';
    }
};
int main()
{
    Time t(12,12,12);
    t.print();
    return 0;
}

输出结果:

12:12:12

5.static变量

5.1.定义

引入static变量,表示这个变量为某个类的所有对象所共用,不单独属于某个对象,而是属于「整个类」

静态数据成员的值对所有对象都是一样的。如果改变它的值,则各对象中该数据成员的值都同时改变。

下面一个图可以表示:图片在类作用域内,可以通过类名和域运算符“∷”引用静态数据成员,而不论类对象是否存在。

5.2.内存空间及初始化

  • 内存空间 静态数据成员不随对象的建立而分配空间,也不随对象的撤销而释放。 静态数据成员是「在程序编译时被分配空间的」,到「程序结束」时才释放空间。

  • 初始化

    • 不能用构造函数初始化赋值;
    • 不能放在主函数中初始化;
    • 在程序定义该类的任何对象之前,对类中的static数据成员单独初始化;

初始化形式: 数据类型  类名::static数据成员名  = 初始化值;

「注意:」

  • 在初始化语句中不必加static。
  • 如果未对静态数据成员赋初值,则编译系统会自动赋予初值0。

5.3.static成员变量

static成员变量声明为公有时,外部可以通过三种方式访问到:

  • 通过对象名打点访问
  • 通过「类名和域运算符“∷”引用静态数据成员」
  • 通过「静态成员函数」进行访问。~静态成员函数下面会介绍。 如果声明为私有的变量,只能通过内部的成员函数间接访问。

代码演示:

#include<iostream>
using namespace std;
class Time
{

private:
    int hour;
    int minute;
    int second;
public:
    static int year;//静态变量
    Time(int hour,int minute,int second)
    {
        this->hour = hour;
        this->minute = minute;
        this->second = second;
    }
    void print()
    
{
        cout<<'year:'<<year<<'\n';
        cout<<hour<<':'<<minute<<':'<<second<<'\n';
    }
};
int Time::year = 2021;//静态变量初始化
int main()
{
 //访问静态公有的变量
    cout<<'year:'<<Time::year<<'\n';
    Time t1(12,12,12),t2(10,10,10);
    t1.print();
    t2.print();
    return 0;
}

运行结果:

year:2021
year:2021
12:12:12
year:2021
10:10:10

可以看到上面的year都是2021,所有的Time对象公用一个静态数据year。

5.4.static成员函数

静态成员函数与静态成员变量几乎是一样的道理,表示对于「同一个类的所有对象」共享的成员函数,一般声明为公有。

「注意:」

  • 静态成员函数没有this指针。静态成员函数不属于某个对象,为该类的所有对象共享,所以静态成员函数没有this指针
  • 静态成员函数可以通过「类名」「对象」直接访问
  • 静态成员函数「只能」直接访问「静态成员变量(函数)」,而不能直接访问普通成员变量(函数)

代码示例:

#include<iostream>
using namespace std;
class Time
{

private:
    int hour;
    int minute;
    int second;
public:
    static int year;
    Time(int hour,int minute,int second)
    {
        this->hour = hour;
        this->minute = minute;
        this->second = second;
    }
    static void print();
};
int Time::year = 2021;//静态变量初始化
void Time::print()
{
    cout<<'year:'<<year<<'\n';
}
int main()
{
    cout<<'year:'<<Time::year<<'\n';
    Time t1(12,12,12),t2(10,10,10);
    t1.print();
    t2.print();
    return 0;
}

运行结果:

year:2021
year:2021
year:2021

偷张图总结以下,嘿嘿嘿~图片

图片

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多