C++面对对象(下)

这篇具有很好参考价值的文章主要介绍了C++面对对象(下)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

 讲解大致内容为初始化列表,explicit关键字,static(静态)成员


目录

初始化列表与函数构造体赋值

函数构造体赋值

初始化列表

使用初始化列表的初始化顺序

使用初始化列表的优点

explicit关键字

static成员(静态)

概念


初始化列表与函数构造体赋值

函数构造体赋值

在创建对象时,编译器会通过调用构造函数,给对象中的各个成员变量一个合适的初始值:

class A
{
    public:
    // 构造函数
    Date(int X = 0, int Y = 0, int Z = 0)
    {
        _X = X;
        _Y = Y;
        _Z = Z;
    }
private:
    int _X;
    int _Y;
    int _Z;
};

注:上述的函数构造体赋值可以进行多次赋值,而下面我们要讲的初始化列表

初始化列表

一、每个成员变量在初始化列表中只能出现一次  因为初始化只能进行一次,所以同一个成员变量在初始化列表中不能多次出现

class A
{
    public:
    // 构造函数
    Date(int X = 0, int Y = 0, int Z = 0)
        :_X(X)
        ,_Y(Y)
        ,_Z(Z)
    {}
private:
    int _X;
    int _Y;
    int _Z;
};

二、类中包含以下成员,必须放在初始化列表进行初始化:

1.引用成员变量  引用类型的变量在定义时就必须给其一个初始值,所以引用成员变量必须使用初始化列表对其进行初始化。

class A
{
    public:
    // 构造函数
    Date(int X = 0, int Y = 0, int Z = 0)
        :_X(X)
        ,_Y(Y)
        ,_Z(Z)
    {}
private:
​
    int& _b = 0;// 创建时就初始化
};

2.const成员变量  被const修饰的变量也必须在定义时就给其一个初始值,也必须使用初始化列表进行初始化。

class A
{
    public:
    // 构造函数
    Date(int X = 0, int Y = 0, int Z = 0)
        :_X(X)
        ,_Y(Y)
        ,_Z(Z)
    {}
private:
    
    const int a = 10;//correct 创建时就初始化
};
 

3.自定义类型成员(该类没有默认构造函数)  如果一个类没有默认构造函数,那么我们在实例化该类对象时就需要传参对其进行初始化,所以实例化没有默认构造函数的类对象必须使用初始化列表对其进行初始化

class B
{
    public:
    // 没有默认构造
    Date(int Big)
      :_Big(Big);
    {}
private:
    int _Big;
};
​
class A
{
    public:
    // 构造函数
    Date(int A = 0)
        :_Big(A)
    {}
private:
    int _A;
    B _Big;
};

 在这里再声明一下,默认构造函数是指不用传参就可以调用的构造函数:

 1.我们不写,编译器自动生成的构造函数。  2.无参的构造函数。  3.全缺省的构造函数。

使用初始化列表的初始化顺序

举个例子:

class A
{
    public:
    // 构造函数
    Date(int X = 0, int Y = 0, int Z = 0)
        :_X(X)
        ,_Y(Y)
        ,_Z(Z)
    {}
private:
    //初始化列表的初始化顺序
    int _X;//1
    int _Y;//2
    int _Z;//3
};

注:初始化列表的初始化顺序为按照你在private的定义从上到下初始化

使用初始化列表的优点

 因为初始化列表实际上就是当你实例化一个对象时,该对象的成员变量定义的地方,所以无论你是否使用初始化列表,都会走这么一个过程(成员变量需要定义出来)。 严格来说:  1.对于内置类型,使用初始化列表和在构造函数体内进行初始化实际上是没有差别的,其差别就类似于如下

1.对于内置类型,使用初始化列表和在构造函数体内进行初始化实际上是没有差别的

2.对于自定义类型,使用初始化列表可以提高代码的效率

explicit关键字

使用这个关键字explicit来修饰构造函数后就不可以使用单参数构造函数的隐式转换

class A
{
public:
    // 构造函数
    Date(int X = 0)
    _X = X;
    {}
    Print()
    {
        cout<< _X <<endl;
    }
private:
    int _X;
};
int main()
{
    A a1 = 100;
    return 0;
}
 

所以在早期的编译器中,当编译器遇到A a1 = 100这句代码时,会先构造一个临时对象,再用临时对象拷贝构造a1;但是现在的编译器已经做了优化,当遇到A a1 = 100这句代码时,这就叫做隐式类型转换

static成员(静态)

概念

 声明为static的类成员称为类的静态成员。用static修饰的成员变量,称之为静态成员变量;用static修饰的成员函数,称之为静态成员函数。静态成员变量一定要在类外进行初始化,它在静态区(内存模型中)。

静态成员它是类中所有成员共享,不属于具体的一个类。

class A
{
private:
    static int _a;
};
int main()
{
    cout << sizeof(A) << endl;
    return 0;
}

它输出的大小为1,因为它是静态成员_a(在静态区),属于整个类。所以计算类的大小或者类对象的大小时,静态成员并不计算。

静态成员变量必须在类外定义初始化

class A
{
private:
    static int _a;
};
int main()
{
    cout << sizeof(A) << endl;
    return 0;
}
int A::_A = 0;//定义初始化

访问静态成员变量的方法

class A
{
public:
    static int _a; //静态,属于整个类
};
// 静态成员变量的定义初始化
int A::_a = 0;
int main()
{
    Test test;
    cout << A._a << endl; //1.通过类对象突破类域进行访问
    cout << A()._a << endl; //3.通过匿名对象突破类域进行访问
    cout << A::_a << endl; //2.通过类名突破类域进行访问
    return 0;
}
  • 第一种为:通过类对象突破类域进行访问

  • 第二种为:通过匿名对象突破类域进行访问

  • 第三种为:通过类名突破类域进行访问

静态成员函数是没有this指针

class A
{
public:
    static void Fun()
    {
        cout << _a << endl; //不能访问非静态成员
        cout << _b << endl; //可以
    }
private:
    int _a; //非静态成员
    static int _b; //静态成员
}

注:静态成员和类的普通成员一样,也有public、private和protected这三种访问级别 

注:

1、静态成员函数可以调用非静态成员函数吗?

  • 不可以。因为非静态成员函数的第一个形参默认为this指针,而静态成员函数中没有this指针,故静态成员函数不可调用非静态成员函数。

2、非静态成员函数可以调用静态成员函数吗?

  • 可以。因为静态成员函数和非静态成员函数都在类中,在类中不受访问限定符的限制。文章来源地址https://www.toymoban.com/news/detail-454387.html

到了这里,关于C++面对对象(下)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包