程序设计-函数/类
函数-参数的传递
实参--参数原样。 s
形参--传递给函数的样子。 x
值传递--c_r是实参的一个拷贝,无法改变实参的值。
void change1(int x){}
指针传递--c_z 也是值传递,只是这个值是是一个指向地址。操作的也是copy后的副本。指针有自己的地址,内容是调用时指向实参地址。
void change3(int *x){}
可以通过这个指向地址,来改变里面的值。
但这个指向地址是改变不了的。
x的值为a--》指向c。复制了一份x'。
可以通过a改变c的内容,但a是改变不了的。
但调用的时候可以用chang3(&x)..调用和声明交叉起来,同一个符号会有两种不同的内涵,很容易迷糊。
c# out int x; 这里有不一样,x是会被清空,原来的值是传不进来的。
引用传递--c_y 纯c没有这种类型.
但和指针传递用change3(&x),效果感觉一样,就写起来这个直接用本体,x=x+10。
void change2(int &x){}
‘别名’---x=s---》adress
编译的时候就把x的地址就写成和s一样了。
void change2(const int &x){}
这样即把地址传过去了,同时又不允许实参被改变。
指针引用传递 --c_x
void (int *&x) {}
相当于指针‘别名’传进去,可以改变里面的地址值了。
和**的关系?--可能也类似于引用的场景情况,需要初始化啥的。
c# ref int x
然后参数定义符号和调用时的符号有交叉混杂。让代码看起来让人头大。
如c_r,c_y--调用时chang(x).应该是系统自动来判断如何传递。
c_z--调用时可以chang(&x),&x就相当于指针*了,
指针*,带不带*又有很多讲究。
复制---参数为引用对象
浅复制-- 系统默认是用““位拷贝”的方式。值对象没问题,指针对象会使指向同一个地址。
深复制-- 要类里面自己实现数据对应情况。 然而类都是很复杂的。不如建一个新的。
java 没有 修饰符 也不能用指针。都是值传送。
如果s为基本类型,那这个值就是内容,是不能改变s值的。相当于c_r
如果s为引用类型(数组,类),那传递过来的是地址, 相当于c_z和c_y的综合。
c_x这种情况呢?c#中一个类的指向都是固定为主为主把。=retrun =new。函数中对类进行填充。在函数中指向另一个类?
java中也是副本传递的,无法改变指向,https://developer.aliyun.com/article/607572。
要实现可能要再包一层,引用类型再包含引用类型。
使用场景
c_z多了一层结构。功能灵活,多了不确定性。
很多时候需求只要c_y这样。c_y需要s已经初始化。
大概s已经有值,然后需要改变用c_y.
s是空的,需要分配地址赋值用c_z。或者需要改变s指向的对象。 通常s申明就是一个指针变量。
这种区别使的程序风格大不一样。参数申明,函数编写。
c++可以直接把数据申明全局变量,然后函数里直接传递操作。java都要声明成数组或类结构。再对其传递操作。
这里的组合很灵活,有些并不合适,有些需要编写者处理好后续,要使用恰当的方式实现需求,像泥潭一样,要深入打磨才有感觉。专门有efficent c++这种书。
动态语言在此基础上裁剪整合成更统一,更便捷理解的方式。
类
抽象维度上分 c++ java
接口-- 全部纯虚函数,定义上没特别关键字 interface
抽象类--部分纯虚函数---不能拿来建对象等等限制 abstract class
普通类 --有虚函数--可以直接用,也提供了改写的余地。
集群---
基类-
关系--纵向--继承
java
--无法重新实现 普通函数 加 final
如果定义了和父类一样的函数,调用时的实现依然是父类的。
--可以重新实现 virtual fun 虚函数 正常函数-java自动实现了虚函数
--必须重新实现 virtual fun=0 纯虚函数 加 abstract
继承后扩展
-- 由于可以继承多个基类,无法直接用superi这样调用。 super.xx
要用 父类名::方法名这样 CScrollView::OnCreate()
基类的无参数构造函数,都会默认执行。
基类的析构函数,用virtual 声明后,也都会默认执行。
Java只能单一继承,但可以实现多个接口。。
调用者--
根据指针的实际对象来调用方法。并不管声明时的指针类型。
类设计在纯粹性和集成性之间的平衡