Re: [问题] 使用指标的时机

楼主: tinlans ( )   2019-09-13 06:33:12
※ 引述《PythonScript (Python)》之铭言:
: 拍谢 真的是 C++ 新手 如果问了蠢问题请见谅
: 有翻过文章翻过书 但是还是不是很确定使用指标的时机
: 以我目前的理解 有错再请提点
: 有 classA, classB 与 classC
: classB 会产生 classA 的物件, 然后存在 classB 的属性中
: 接着 classC 会去存取 classB, 也会使用 classB 中存 classA 的属性
: 如果在 classB 中 classA objectA;
: 未来某个时刻有可能会发生 classC 存取 classB 中存 classA 的属性时
: 该属性可能会消失或被取代
: 如果在 classB 中 classA* objectA = new objectA()
: 就不会有上述描述情况的发生
: 可以这样理解吗?
你需要学习的不是指标这一语言机制的使用时机,而是物件导向的知识。
“未来某个时刻有可能会发生 classC 存取 classB 中存 classA 的属性时,
该属性可能会消失或被取代”
这段话乍听之下会像是 GoF design patterns 的 strategy pattern,
但是往后看到这段就会发现其实你正处于自行摸索阶段:
“如果在 classB 中 classA* objectA = new objectA(),
就不会有上述描述情况的发生”
从这段话来看,你决定是否使用指标,是为了避免 objectA 不见。
classA 的物件生命周期不受控于 classB,
不管 objectB 的状态变得如何,你都希望 objectA 可以继续存活于某处。
这在 OOD (物件导向设计) 阶段,一般被模塑为 aggregation 关系,又叫 owns-a 关系。
但是 classB 并不控制 classA 的生命周期,所以你不该在 classB 中 new 出 objectA,
而是应该在其它地方 new 出 objectA,再把它透过 constructor 或 method 传进去存。
你让 classB 去把 objectA new 出来,这样也应该让 classB 负责 delete 它。
不然你的物件创造和销毁机制就会散落在程式的不同地方,这样就是个很糟的程式。
(以后你在 C++ 学到的 smart pointer 的确乍看之下会不是由 classB 负责销毁,
但实际上它还是会因为 classB 的某些行为而间接引发销毁,这意义上其实没有变化。)
这种情况下听起来要描述的是 composition 关系,又称为 is-a-part-of 关系。
因为你是把 objectA 存到 objectB 里面,不是想用的时候才 new 出来,
一旦用完就马上把它销毁掉,所以不会是 dependency 关系 (也叫 use-a 关系)。
从你描述的前后文来看,就像是 owns-a 和 is-a-part-of 关系的混合版。
这是因为你不熟悉物件导向,而程式语言给予太大的自由,导致你写出了这种古怪程式。
熟悉物件导向的人一听就会觉得浑身不对劲,然后会希望你能先去补足相关观念。
实际上这段话在物件导向里也是破坏封装的一种行为:
“接着 classC 会去存取 classB,也会使用 classB 中存 classA 的属性”
未来你学过以后就会知道这种事情应该避免。
语言机制如同一块一块形状不同的积木,积木怎么使用的确是可以随心所欲。
但是经过诸多错误尝试之后,你会发现要把积木组成某个你想像的样子,
依循着某些规则去组合积木,可以让结构最稳固,成功率也最高。
于是你渐渐就不会再随便去组积木,而是依循一些你归纳出来的法则去组。
物件导向概念是前人诸多错误尝试后传承下来的一个经验,学习它就能少走很多冤枉路。
比较遗憾的是 C++ 不是物件导向领域的主流程式语言,
相关书籍的范例程式码大都不是以 C++ 写成,可能是 Java、C# 等等。
你想学物件导向,可能还得稍微熟悉一下其它语言跟 C++ 的差异,并将它们转成 C++。
要想在 C++ 开发物件导向程式,你得变得比现在更博学多闻。
: 其次就是 如果有个变量 variableA
: 我有用指标变量 pointerA 指向 variableA
: 这样 variableA 应该是不会消失 直到我 delete 他
: 那如果有一系列的 variableA 变量指向它们
我想你这边要说的是一系列的 pointerA。
: 我把它们整理成一个 vectorB
: vectorB = vector<pointerA>
: 如果怕 vectorB 弄丢 那需要再用一个 pointerB 指向 vectorB 吗?
看起来你好像非常担心把什么东西弄丢。
然而若是你没保管好 pointerB,你还是会把 pointerB 和 vectorB 一起弄丢。
这点物件导向分析和设计都可以让你保管好它们,倒是不用太过于操心。
vector 这种东西一般不会用 poinier 去指向它,它只是一个低阶资料。
正常来说它只会是 class 中的一个 private data member,所以是弄不丢的。
pointer 在 C++ 中是让你动态抽换指涉对象的一个机制,
也是启用多型和动态系结机制的一个语言设施,并没有防止你弄丢任何东西的功能。
要避免弄丢什么,你要学的应该是如何规划和设计你的程式。
作者: PythonScript (Python)   2019-09-13 08:52:00
我一直觉得 C++ 的变量会突然消失应该不是这么一回事 应该是我有误会什么我想应该是 pass by value 的问题
作者: VictorTom (鬼翼&娃娃鱼)   2019-09-13 15:45:00
推:)

Links booklink

Contact Us: admin [ a t ] ucptt.com