正确处理类的复合关系------新标准c++程序设计
假设要编写一个小区养狗管理程序,该程序需要一个“主人”类,还需要一个“狗”类。狗是有主人的,主人也有狗。假定狗只有一个主人,但一个主人可以有最多10条狗。该如何处理“主人”类和“狗”类的关系呢?下面是一种直观的写法:
#include<iostream>
using namespace std;
class CDog;
class CMaster
{
CDog dogs[10];
int dog_num;
};
class CDog
{
CMaster m;
};
int main()
{
}
这种写法是无法通过编译的。因为尽管提前对CDog类进行了声明,但编译到第4行时,编译器还是不知道CDog类的对象是什么样的,所以无法编译定义dog对象的语句。而且这种“人中有狗,狗中有人”的做法导致了循环定义。避免循环定义的方法是在一个类中使用另一个类的指针,而不是对象作为成员变量。例如:
#include<iostream>
using namespace std;
class CDog;
class CMaster
{
CDog* dogs[10];
int dog_num;
};
class CDog
{
CMaster m;
};
int main()
{
}
上面这种写法在第4行定义了一个CDog类的指针数组在为CMaster类的成员对象。指针就是地址,所以编译器编译到此时不需要知道CDog类是什么样子。这种写法的思想是:当一个CMaster对象养了一条狗时,就有new运算符动态分配一个CDog类的对象,然后在dogs数组中找一个元素,让它指向动态分配的CDog对象。
这种写法还是不够好。问题出在CDog对象中包含了CMaster对象。在多条狗的主人相同的情况下,多个CDog对象中的CMaster对象都代表同一个主人,这造成了没有必要的冗余——一个主人用一个CMaster对象表示足矣,没有必要对应于多个CMaster对象。而且,在一对多的情况下,当主人的个人信息发生变化时,就需要将与其对应的、位于多个CDog对象中的CMaster成员变量m都找出来修改,这毫无必要,而且麻烦。
正确写法:
#include<iostream>
using namespace std;
class CMaster;
class CDog
{
CMaster* pm;
};
class CMaster
{
CDog dogs[10];
int dog_num;
};
int main()
{
}
这样,主人相同的多个CDog对象,其pm指针都指向同一个CMaster对象。实际上,一个主人未必都养10条狗,因此处于节省空间的目的,在CMaster类中设置CDog类对象的指针数组,而不是对象数组,也是一种写法
新标准c++程序设计
正确处理类的复合关系------新标准c++程序设计的更多相关文章
- 类与类之间的两种关系------新标准c++程序设计
在c++中,类和类之间有两种基本关系:复合关系和继承关系. 复合关系也称为“has a”关系或“有”的关系,表现为封闭类,即一个类以另一个类的对象作为成员变量. 继承关系也称为“is a”关系或“是” ...
- 类的互相包含------新标准c++程序设计
#include<iostream> using namespace std; class A; class B{ public: void f(A* pt){}; } class A{ ...
- 多态实现的原理------新标准c++程序设计
“多态”的关键在于通过基类指针或引用调用一个虚函数时,编译时不确定到底调用的是基类还是派生类的函数,运行时才确定.例子: #include<iostream> using namespac ...
- 封闭类------新标准c++程序设计
封闭类: 一个类的成员变量如果是另一个类的对象,就称之为“成员对象”.包含成员对象的类叫封闭类. #include<iostream> using namespace std; cl ...
- string类------新标准c++程序设计
定义: string类是STL中basic_string模板实例化得到的模板类.其定义如下: typedef basic_string<char>string; 构造函数: string类 ...
- this指针------新标准c++程序设计
背景: c++是在c语言的基础上发展而来的,第一个c++的编译器实际上是将c++程序翻译成c语言程序,然后再用c语言编译器进行编译.c语言没有类的概念,只有结构,函数都是全局函数,没有成员函数.翻 ...
- 在成员函数中调用虚函数(关于多态的注意事项)------新标准c++程序设计
类的成员函数之间可以互相调用.在成员函数(静态成员函数.构造函数和析构函数除外)中调用其他虚成员函数的语句是多态的.例如: #include<iostream> using namespa ...
- 多态的作用-游戏编程展示------新标准c++程序设计
游戏软件的开发最能体现面向对象设计方法的优势.游戏中的人物.道具.建筑物.场景等都是很直观的对象,游戏运行的过程就是这些对象相互作用的过程.每个对象都有自己的属性和方法,不同对象也可能有共同的属性和方 ...
- 复制构造函数被调用的三种情况------新标准c++程序设计
1.当用一个对象去初始化同类的另一个对象时,会引发复制构造函数被调用.例如,下面的两条语句都会引发复制构造函数的调用,用以初始化c2. C c2 (c1); C c2=c1; 这两条语句是等价的.注意 ...
随机推荐
- PHP生成唯一固定长度邀请码
function create_invite_code() { $code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; $rand = $code[rand(0,25)] .str ...
- log4net 使用总结- (1)在ASP.NET MVC 中使用
1. 去官网下载log4net.dll,增加引用到站点下(你也可以通过nuget 安装) http://logging.apache.org/log4net/download_log4net.cgi ...
- 不同浏览器对于html5 audio标签和音频格式的兼容性
音频格式 Chrome Firefox IE9 Opera Safari OGG 支持 支持 支持 支持 不支持 MP3 支持 不支持 支持 不支持 支持 WAV 不支持 支持 不支持 支持 不支持 ...
- 1.4 Application应用
使用celery第一件要做的最为重要的事情是需要先创建一个Celery实例,我们一般叫做celery应用,或者更简单直接叫做一个app.app应用是我们使用celery所有功能的入口,比如创建任务,管 ...
- 最长公共子序列(lcs)
给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的). 比如两个串为: abcicba abdkscab ab是两个串的子序列,abc也是,abca也是,其中abca是这两个字符 ...
- Objective-C 基础语法log打印那些事儿(一)
Objective-C 基础语法详解 雨松MOMO原创文章如转载,请注明:转载至我的独立域名博客雨松MOMO程序研究院,原文地址:http://www.xuanyusong.com/archives/ ...
- 成都国嵌-嵌入式linux必修实验手册…
emouse收集整理,转载请注明: emouse的技术专栏 博客园:http://www.cnblogs.com/emouse/ CSDN:http://blog.csdn.net/haozi_198 ...
- LED电视与液晶电视的区别
[LED电视与液晶电视的区别] 目前LED电视全部是采用了LED背光的液晶电视,本质上而言,还是液晶电视.这与真正的LED电视是两个完全不同的概念.如今通常把LED背光电视称为LED电视,采用CCFL ...
- 4-3 线程安全性-原子性-synchronized
原子性它提供了互斥访问,同一时刻只能有一个线程来对它进行操作.能保证同一时刻只有一个线程来对其进行操作的,除了Atomic包之外,还有锁.JDK提供锁主要分两种,synchronized是一个Java ...
- laravel 验证机制validation
Laravel 中 validation 验证 返回中文提示 全局设置 自己建一个zn文件夹,然后把en的4个文件全复制过去,修改validation.php的代码为下面的内容,然后在app.php修 ...