域名抢住网站,集团网站建设方案书,jsp购物网站开发教程,c2c二手车交易平台欢迎来到我的Blog#xff0c;点击关注哦#x1f495;
前言 前面已经对类和对象有一定的了解#xff0c;接下来再次深入的了解一下。 一、深入理解构造函数
构造函数体赋值#xff1a;
虽然上述构造函数调用之后#xff0c;对象中已经有了一个初始值#xff0c;但是不能…欢迎来到我的Blog点击关注哦
前言 前面已经对类和对象有一定的了解接下来再次深入的了解一下。 一、深入理解构造函数
构造函数体赋值
虽然上述构造函数调用之后对象中已经有了一个初始值但是不能将其称为对对象中成员变量的初始化 构造函数体中的语句只能将其称为赋初值而不能称作初始化。因为初始化只能初始化一次而构造函数体 内可以多次赋值
class Date
{
public:Date(int year, int month, int day){_year year;_month month;_day day;}private:int _year;int _month;int _day;
};初始化列表
初始化列表是在C中构造函数中用于初始化类成员变量的一种机制。
它以冒号(:)开始后跟以逗号分隔的成员变量列表每个成员变量后面可以跟一个初始化表达式。
class Date
{Date(int year, int month, int day):_year(year), _month(month), _day(day){}private:int _year;int _month;int _day;
};初始化列表使用的关键点
初始化顺序成员变量在初始化列表中的初始化顺序遵循它们在类定义中声明的顺序而不是初始化列表中出现的顺序。 严格执行声明顺序即初始化顺顺序,下面的代码在语法上先进行capacity的初始化。 下面的程序会崩溃 先进行_a的开辟空间capacity没有进行初始化导致capacity 是随机值。赖皮空间随机值。
class Stack
{
public:Stack(int capacity)//错误:_capacity(capacity), _a((int*)malloc(sizeof(int)* _capacity)),_size(0){}
private:int* _a;int _capacity;int _size;
};特定成员的初始化对于常量成员、引用成员以及没有默认构造函数的自定义类型成员必须在初始化列表中进行初始化因为这些成员不能在构造函数体内被赋值。 引用和const修饰都是在初始化定义的。 class A
{
public:A(int a):_a(a){}
private:int _a;
};class B
{
public:B(int a, int ref):_aobj(a),_ref(ref),_n(10){}
private:A _aobj; // 没有默认构造函数int _ref; // 引用const int _n; // const
};性能优势使用初始化列表可以避免成员变量先默认构造后再赋值的额外步骤特别是对于资源管理类如持有指针或动态分配内存的类这可以提高效率 成员变量的初始化只能进行一次无论是在初始化列表中还是在构造函数体内都不能重复初始化同一个成员变量。 class Date
{Date(int year, int month, int day):_year(year), _month(month), _day(day)
// ,_day(day) //在加入这句就是错误的初始化只能进行一次。{}private:int _year;int _month;int _day;
};成员变量的缺省值如果在类成员声明时指定了缺省值这些值将在进入构造函数体之前被用于初始化列表 如果在定义的时候进行了传递参数即优先使用传递的参数。
class Date
{Date(int year, int month, int day):_year(year), _month(month), _day(day){}private:int _year 1;int _month 1;int _day 1;
};初始化列表的灵活性除了初始化成员变量初始化列表还可以用于动态内存分配、类型转换赋值等操作
二、explicit 关键字
explicit关键字用于修饰类的构造函数以防止隐式类型转换。当一个构造函数被声明为explicit时它不能参与隐式转换只能通过直接初始化或拷贝初始化的方式显式调用。
class Date
{
public:// 1. 单参构造函数没有使用explicit修饰具有类型转换作用// explicit修饰构造函数禁止类型转换---explicit去掉之后代码可以通过编译explicit Date(int year):_year(year){}Date operator(const Date d){if (this ! d){_year d._year;_month d._month;_day d._day;}return *this;}
private:int _year;int _month;int _day;
};void Test()
{Date d1(2024);d2 2024;
}三、static成员
声明为static的类成员称为类的静态成员用static修饰的成员变量称之为静态成员变量用static修饰的 成员函数称之为静态成员函数。静态成员变量一定要在类外进行初始化
static成员的特性 静态成员为所有类对象所共享不属于某个具体的对象存放在静态区 静态成员变量必须在类外定义定义时不添加static关键字类中只是声明 类静态成员即可用 类名::静态成员 或者 对象.静态成员 来访问 静态成员函数没有隐藏的this指针不能访问任何非静态成员 在下面的例子中 没有this指针 func1 访问不了 func2 class Date
{
public:static void func1(){}void func2(){}private:int _year;int _month;int _day;static int count;
}; 静态成员也是类的成员受public、protected、private 访问限定符的限制
四、友元
友元概念
友元friend是一种特殊的关系它允许一个函数或类访问另一个类的私有成员或保护成员。友元关系不是类的成员关系而是一种独立的访问权限关系。通过友元可以在不破坏封装性的前提下实现类之间的数据共享和功能协作
修改print
正常访问重载操作,是访问不到 Date的private成员变量的friend很好的帮助我们突破了这个界限。
ostream operator(ostream out,const Date d)
{out d._year 年 d._month 月 d._day 日 endl;return out;
}class Date
{friend ostream operator(ostream out, const Date d);public:Date(int year 1, int month 1, int day 1): _year(year), _month(month), _day(day){}private:int _year;int _month;int _day;
};
五、内部类
内部类的特点
独立性内部类是一个独立的类不隶属于外部类。访问权限内部类可以定义在外部类的任何访问级别中其访问外部类成员的权限取决于其自身的定义位置。访问外部类成员内部类可以直接访问外部类的static和enum成员但不能直接访问外部类的非静态成员。大小关系内部类的大小与外部类无关sizeof(外部类)不会包括内部类的大小。创建方式内部类的对象可以通过外部类的作用域限定符创建例如外部类名::内部类名。生命周期内部类的对象可以在栈上或堆上创建其生命周期取决于创建方式。
{
private:static int k;int h;
public:class B // B天生就是A的友元{public:void foo(const A a){cout k endl;//OKcout a.h endl;//OK}};
};int A::k 1;int main()
{A::B b;b.foo(A());return 0;
}编程题目友元的巧妙应用
求123…n要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句A?B:C。
数据范围 0≤2000n≤200 进阶 空间复杂度 O*(1) 时间复杂度 O*(n)
class Solution {
public:class B{public:B(){ret i;i;}};
int Sum_Solution(int n) {B a[n];return ret;
}private:
static int ret ;
static int i;
};int Solution:: ret 0;
int Solution:: i 1;