类和组合

对象数组和对象指针

可以进行定义对象数组对象指针
一维对象数组定义方法
类名 数组名[下标表达式];
类名 数组名[下标表达式]={类名(…),类名(…)};
//第一种默认调用系统给的无参构造函数
//第二种通过后面{}决定

class A
{int x,y;
public:A(){x=0,y=0;}A(int x,int j=0){x=i,y=j;}};如果这样定义的话A obj[4]={1,2};//如何传递?obj[0]出态为x=1,y=0//obj[1]初态为x=2,y=0

对象数组成员的引用同样注意限制性
————————————————————
对象指针
对象所占据的内存空间用于存放数据成员,对象的存储空间的起始地址就是对象的指针!!! 定义方法
类名 *对象指针名
访问方法

(*对象指针名).成员名
对象指针名->成员名
!!但要注意访问是否合法还要保证访问成员是公有成员!!

所有指针必须先赋值才能被使用

!!对象指针也是指针 和其他指针使用方法是一样的!!

this指针----自引用指针
①当对象被赋初值之后,就会出现一个隐藏的指针,这个对象的this指针就??指向!!内存中保存该对象数据的存储空间的首地址
②另外在类的成员函数中是可以使用这个this 指针的

class CMyclass
{ private:CMyclass *this;...public:CMyClass(){...}...};

一般不使用 使用的话就是需要在成员函数的实现中访问this所指的对象本身,而不是其各个成员
比较不错的例子 理解this指针

#include<iostream.h>
class ThisSample
{ int n;
public:void SetValue(int m){n=m;}void AddValue(int m){ThisSample q;//函数内部临时对象????//???q.n=n+m;//n相当于this->n n+m赋给了q.n*this=q;//把q复制给this指针所指的那个对象//没调用复制构造函数}void Display(){cout<<"n="<<n<<endl;}void main(){ ThisSample s;s.SetValue(10);s.Display();s.AddValue(5);s.Display();}

————————————————————
类的组合
就是类中内嵌对象成员
面向对象:复杂对象进行分解抽象,复杂对象分解为简单对象的组合。

对象成员的初始化
成员初始化列表:
例 CPoint::CPoint(int xx,int yy):x(xx),y(yy)
{cout<<“constructor called”;}

!调用构造函数时先执行成员初始化列表 再按顺序执行构造函数体内语句
!与说明普通对象不同,在说明对象成员时并没有创建该对象,等创建外层类的实例时会为对象成员分配内存初始化
!类中有对象成员,先执行所有对象成员构造函数,再执行当前类的构造函数体

代码理解:

class CPoint
{private:
int x,y;public:
CPoint(int i=0,int j=0){x=i,y=j;}
CPoint(CPoint &p);
int getx(){return x;}
int gety(){return y;}
};
CPoint::CPoint(CPoint &p)
{x=p.x;y=p.y;cout<<"复制构造函数调用"<<endl;}class CDistance
{ private:CPoint p1,p2;double dist;public:CDistance(CPoint xp1,CPoint xp2);
};
//进行构造函数的定义
CDistance::CDistance(CPoint xp1,CPoint xp2):p1(xp1),p2(xp2)//成员初始化列表
{ cout<<"CDistance构造函数被调用"<<endl;double x=1;double y=2;
}void main()
{CPoint myp1(1,1),myp2(4,5);CDistance myd(myp2,myp2);}思考:怎么输出呢??Thought:main函数先定义了两个类对象其次进行CDistance初始化CDistance构造函数是怎样被调用的呢?NO.1:首先进行形实结合 把myp1 myp2赋给构造函数的形参xp1 xp2 ==这时会自动调用CPoint的复制构造函数==NO.2:接下来出现在成员初始化列表中,用已存在的xp1,xp2对象初始化成员初始化列表中的形参

—————————————————————————
位运算
按位与(&) 按位或(||) 按位抑或 按位取反 移位
C++中有两个移位运算符:左移运算(<<)和右移运算(>>),都是二元运算符。
左移是按照指定的位数将一个数的二进制值向左移位,左移后,低位补0,移出的高位舍弃。
右移是按照指定的位数将一个数的二进制向右移位,右移后移出的低位舍弃,如果是无符号数则高位补0;如果是有符号数,则高位补符号位
① 例:一int型变量a的值为-8,则a在内存中的二进制补码值为11111000,于是表达式a>>2的值为-2,补码变为11111110,对应值为-2
②例:表达式2<<1的值为4,移位前2的补码值为:00000010,移位后补码变为000000100,值为4

移位运算的结果是位运算表达式(a>>2和2<<1)的值,移位运算符左边表达式的变量值并不会改变

——————————————————————————

静态数据成员的声明和使用:
类中声明 例:static int total;
类外进行(必须) int CPoint::total=0;
【不能在构造函数中初始化 理解下】

访问:
①公有的: 类名::对象名. 引用
②私有的:只能在类内引用,类外没法用(因为是私有的)

静态成员函数
声明:
前面加static

访问:
①类名:: 访问
②对象名. 访问

说明:
静态成员函数可以直接引用该类的静态数据成员函数,而不能直接引用非静态数据成员
(静态成员函数定义类就存在了 非静态数据成员实例化对象时才存在 可以这么理解吧)

静态成员函数引用非静态数据成员,通过参数传递得到对象名,通过对象名引用间接实现

class CTest
{int x;
public:static void f(CTest a){ cout<<x<<endl;//错误!cout<<a.x<<endl;}};

静态成员函数无this指针

练习
#include<iostream.h>
class CPoint
{ int x,y;static int n;public:构造函数CPoint(int xx=0,int yy=0){x=xx;y=yy;n++;}复制构造函数CPoint(CPoint &p){x=p.x;y=p.y;n++;}析构函数~CPoint(){n--;}int get_x(){return x;}int get_y(){return y;}静态函数static void get_n(){coun<<"obj"<<n<<endl;}
};静态数据成员初始化int CPoint::n=0;

————————————————————————————

友元

【B类内嵌A类对象,但是B的成员函数没法直接访问A的私有成员】
友元:
<1>某类中嵌套一个类,该类普通成员函数可以访问那个类中的数据
<2>一个普通函数可以访问那个类中的数据

实现
①友元函数(普通函数+其他类的成员函数)
<1>friend <类型标识符> <友元函数名>(参数表)
<2>friend <类型标识符> 类名:: <友元函数名>(参数表)

②简单使用 普通函数
<1>

class CPoint
{ double x,y;
publicCPoint(double xx=0,double yy=0){x=xx;y=yy;}double getx(){return x;}double gety(){return y;}//声明,在哪声明都行。这样想,它只是我的朋友,故不是本类的成员函数//所以放哪声明都行,跟类无关,只是为了用它来访问类中私有数据friend double get_distance(CPoint &p1,CPoint &p2);
};
double get_distance(CPoint &p1,CPoint &p2)
{
//传对象引用可以访问私有数据和公有数据
//!!这时候是友元函数起作用!!
return p1.x+p1.y+p2.x+p2.y;
}
void main()
{CPoint my(1,1),my2(1,1);
//调用也是直接调用,因为这个函数只是那个类的朋友,不是本类的成员函数
cout<<"cout"<<get_distance(my,my2);
}

<2>(跟<1>差不多)

class CPoint
{ double x,y;
publicCPoint(double xx=0,double yy=0){x=xx;y=yy;}double getx(){return x;}double gety(){return y;}friend double get_distance();
};
double get_distance()
{ CPoint p1(1,2);
CPoint p2(2,3)
return p1.x+p1.y+p2.x+p2.y;
}
//调用也是直接调用,因为这个函数只是那个类的朋友,不是本类的成员函数

③简单使用(感觉知道就行) 其他类的成员函数

class CPoint;
class CTest
{ ...friend double get_distance(CPoint &p1,CPoint &p2);...
};
class CPoint
{CPoint p1;
CPoint p2;
//声明
friend double CTest::get_distance(CPoint &p1,CPoint &p2);
};
double CTest::get_distance(CPoint &p1,CPoint &p2)
{...
}
//调用不是直接调用,得先构造CTest对象,通过**对象.**的形式调用。

总结:
其实差不多,A类中的友元函数可以是普通的函数,也可以是其他类的函数,不同情况对应不同的声明,只要明白一点,友元函数不属于A类本身,它只是用于调用A类的私有数据成员罢了,这时刻记住。

④简单实用 友元类
friend class <友元类名>
其实就是范围扩大了,A类为B类友元类,就在B类中声明:friend class A;,A类就是B类的朋友了,A类中所有函数,数据成员对于B类中的私有数据啥的都能访问,③扩展

class CPoint;
class CTest
{ ...double get_distance(CPoint &p1,CPoint &p2);void test(CPoint &p1);...
};class CPoint
{CPoint p1;
CPoint p2;
//声明友元类
friend class CTest;
};//调用不是直接调用,得先构造CTest对象,通过**对象.**的形式调用。

总结:
分为友元类和友元函数 懂得如何去理解
————————————————————————————

常类型

const修饰符
例:#define的不安全性

#include<iostream>
using namespace std;
main() {int a=1;//define只是字面替换 在预编译时进行了字符替换#define T1 a+a#define T2 T1-T1cout<<"T2 is "<<T2<<endl;return 0;}//输出结果为T2 is 2

const使用

#include<iostream>
using namespace std;
main() {int a=1;//这个常量是有类型 占用存储单元,有地址,可以用指针指向它const T1=a+aconst T2=T1-T1cout<<"T2 is "<<T2<<endl;return 0;}//输出结果 T2 is 0

const与指针组合使用

//(1)常量指针:是指*指针变量**指向**常量**的*。
const char *pc="abcd";//声明指向**常量**的指针右左法则(pc is a pointer to const char)
pc[3]="X";//编译时出现错误
pc="efgh"//正确,指针本身是一个**变量**//(2)指针常量:是指**指针的常量**,指向**变量**的。
char * const pc="abcd"; //指针常量 必须在声明的时候进行初始化 右左法则   (pc is a const point to character)
pc[3]="x";//正确
pc="efgh";//编译时出现错误//(3)指向常量的指针常量:指针是一个常量(不可以修改指向,指针指向的也是一个常量)
const char *const p="abcd";

const修饰做函数形参

//const <类型标识符> &<引用名>
void display(const int &r)
{cout<<"r="<<++r<<endl;//错误! 常引用没法改变
}
//有时会用到 这个应该用的比较多

const对象 const函数(知道就行)

const <类名> <对象名>
//必须同时初始化 实例化对象啥都没法改变(数据成员)
//声明const对象有啥用? 好像没啥用
void diaplay() const;
//const对象可以调用const修饰的成员函数。。
//用的少 开发可能用

说明:如果const修饰int型常量,则关键字int可以省去。
常量一旦建立,程序中任何地方则不能再改
const常量可以有自己的数据类型
函数参数也可以用const说明,用于保证实参在该函数内部不能改动

——————————————————————————

动态内存分配

C语言中动态内存分配有malloc colloc函数吧
1. new运算符
char CBuffer = new char[256];*
*CBuffer[1]=‘a’;
(CBuffer+5)=‘c’;

–成功:T类型的指针,指向新分配的内存 并且分配的内存空间是连续的
–失败:0(NULL)


2.delete运算符  就是释放内存
int *pInt = new int;
delete pInt;//删除单个指针**
char *CBuffer = new char[256];
delete []CBuffer;
3.面向对象中
class R
{
R(){ }
};void main()
{R  *p;p=new R();cout<<p->area()<<endl;//Java中摒弃了指针 多好。。delete p;//释放p指向的内存空间 会调用析构函数
}

**说明:**delete删除的只能是new运算符创建的对象
这两使用比较灵活

C++学习第三天——类的组合+友元函数+常类型+动态内存分配相关推荐

  1. 【C++】C++类的学习(三)——运算符重载与友元函数

    [fishing-pan:https://blog.csdn.net/u013921430转载请注明出处] 前言 前面的两篇博文中介绍了类的一些基本特性,今天讲一讲运算符重载和友元. 运算符重载 运算 ...

  2. 【C语言进阶学习笔记】五、动态内存分配(爆肝吐血力作,强烈建议收藏!!!)

    前言 现代计算机基本都是基于冯诺伊曼结构体系设计出来的,冯诺伊曼结构体系的核心就是"存储程序",将程序(指令集)和数据以同等地位存储在内存中.但是我们的内存空间并不是无限大的,所以 ...

  3. 【C语言进阶深度学习记录】三十三 C语言中动态内存分配

    如何在程序运行的时候动态给程序分配内存? 文章目录 1 动态内存分配的意义 1.1 C语言中如何动态申请内存空间 1.2 malloc和free的用法 1.3 calloc与realloc 1.31 ...

  4. 初入c++(三)this指针,友元函数,友元类

    1.c++中的this指针 指向当前对象,通过它可以访问当前对象的所有成员.当前对象就是正在使用的对象: 在类的内部使用,可以访问所有的成员,public,private,protect this只能 ...

  5. C++ Primer Plus学习(十一)——类和动态内存分配

    类和动态内存分配 动态内存和类 静态类成员 特殊成员函数 string类的改进 构造函数中的new 返回对象 指向对象的指针 成员初始化列表(member initializer list) 动态内存 ...

  6. 大数据HiveSQL学习笔记三-查询基础语法以及常用函数

    大数据HiveSQL学习笔记三-查询基础语法以及常用函数 一.基础语法 1.SELECT -列名- FROM -表名- WHERE -筛选条件- 如:需要根据城市,性别找出匹配的10个用户 user_ ...

  7. 第12章-cpp类和动态内存分配

    本章内容包括: • 对类成员使用动态内存分配. • 隐式和显式复制构造函数. • 隐式和显式重载赋值运算符. • 在构造函数中使用new所必须完成的工作. • 使用静态类成员. • 将定位new运算符 ...

  8. 类和动态内存分配——C++ Prime Plus CH12

    ①动态内存和类 1.复习示例和静态类成员 使用程序复习new和delete用法. // badstring.h文件 #include<iostream> #ifndef STRING_BA ...

  9. C语言学习笔记10-指针(动态内存分配malloc/calloc、realloc、释放free,可变数组实现;Tips:返回指针的函数使用本地变量有风险!;最后:函数指针)

    C语言:指针 1. 指针:保存地址的变量 *p (pointer) ,这种变量的值是内存的地址.   取地址符& 只用于获取变量(有地址的东西)的地址:scanf函数-取地址符   地址的大小 ...

最新文章

  1. WebService之soap类型的服务和rest类型的服务
  2. 【操作系统】进程 与 线程 详解(以及二者的比较)
  3. 微软宣布在机器翻译方面取得突破,中翻英可达人类水平
  4. 深入剖析防火墙策略的执行过程
  5. CentOS7 安装 mysql8
  6. [Qt教程] 第34篇 网络(四)FTP(二)
  7. U盘快速​安装Ubuntu系统
  8. 2021-4-1 多校省选模拟赛
  9. FROONT – 超棒的可视化响应式网页设计工具
  10. hue 查询 hbase 操作相关参考
  11. linux find 拷贝,通过find命令寻找文件并拷贝到一个指定目录方法详解
  12. 关于 java 实现 语音朗读
  13. 菲波那契数列(信息学奥赛一本通-T1188)
  14. Python中math模块的使用
  15. 人脸识别考勤机软件驱动安装和设置
  16. MySQL忘记密码应当如何重置
  17. 全球及中国EOG放大器行业运营前景与发展动态研究报告2022版
  18. 在函数前面加上WINAPI、CALLBACK等是什么意思
  19. 设置div高度等于屏幕高度
  20. android筛选功能代码,Android中 TeaScreenPopupWindow多类型筛选弹框功能的实例代码

热门文章

  1. Good Luck!
  2. viper12a引脚功能图_viper12a各脚电阻值 电磁炉开关电源ICVIPer12A各脚正常工作电压是多少?...
  3. 11个网络工程师必备实用软件
  4. 鼠标计算机,事实:计算机鼠标在哪里?
  5. Win10配置IIS与 C#/.net项目的发布与IIS部署
  6. 史上最全! 瑞芯微RK3568核心板评估板资源分享!
  7. Axure元件-动态面板介绍
  8. uniapp中页面元素转图片APP端
  9. 内核调试:一次多线程调试与KASAN检测实例
  10. 调试经验——Excel中去除单元格内的换行符(Chr(10))的四种方法