假设要编写一个小区养狗管理程序,该程序需要一个“主人”类,还需要一个“狗”类。狗是有主人的,主人也有狗。假定狗只有一个主人,但一个主人可以有最多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++程序设计的更多相关文章

  1. 类与类之间的两种关系------新标准c++程序设计

    在c++中,类和类之间有两种基本关系:复合关系和继承关系. 复合关系也称为“has a”关系或“有”的关系,表现为封闭类,即一个类以另一个类的对象作为成员变量. 继承关系也称为“is a”关系或“是” ...

  2. 类的互相包含------新标准c++程序设计

    #include<iostream> using namespace std; class A; class B{ public: void f(A* pt){}; } class A{ ...

  3. 多态实现的原理------新标准c++程序设计

    “多态”的关键在于通过基类指针或引用调用一个虚函数时,编译时不确定到底调用的是基类还是派生类的函数,运行时才确定.例子: #include<iostream> using namespac ...

  4. 封闭类------新标准c++程序设计

      封闭类:  一个类的成员变量如果是另一个类的对象,就称之为“成员对象”.包含成员对象的类叫封闭类. #include<iostream> using namespace std; cl ...

  5. string类------新标准c++程序设计

    定义: string类是STL中basic_string模板实例化得到的模板类.其定义如下: typedef basic_string<char>string; 构造函数: string类 ...

  6. this指针------新标准c++程序设计

    背景:   c++是在c语言的基础上发展而来的,第一个c++的编译器实际上是将c++程序翻译成c语言程序,然后再用c语言编译器进行编译.c语言没有类的概念,只有结构,函数都是全局函数,没有成员函数.翻 ...

  7. 在成员函数中调用虚函数(关于多态的注意事项)------新标准c++程序设计

    类的成员函数之间可以互相调用.在成员函数(静态成员函数.构造函数和析构函数除外)中调用其他虚成员函数的语句是多态的.例如: #include<iostream> using namespa ...

  8. 多态的作用-游戏编程展示------新标准c++程序设计

    游戏软件的开发最能体现面向对象设计方法的优势.游戏中的人物.道具.建筑物.场景等都是很直观的对象,游戏运行的过程就是这些对象相互作用的过程.每个对象都有自己的属性和方法,不同对象也可能有共同的属性和方 ...

  9. 复制构造函数被调用的三种情况------新标准c++程序设计

    1.当用一个对象去初始化同类的另一个对象时,会引发复制构造函数被调用.例如,下面的两条语句都会引发复制构造函数的调用,用以初始化c2. C c2 (c1); C c2=c1; 这两条语句是等价的.注意 ...

随机推荐

  1. PHP中GD库的使用

    1.基本步骤 <?php /** * Created by PhpStorm. * User: jiqing * Date: 18-4-9 * Time: 上午9:34 * 熟悉步骤 */ // ...

  2. python's twenty ninthday for me 模块和包

    模块 和 脚本的 区别:   如果一个py文件被导入了,就是一个模块. 如果这个py文件被直接执行,这个被直接执行的文件就是一个脚本. 模块:1,没有具体的调用过程.2,能对外提供功能. pyc文件: ...

  3. springboot成神之——ioc容器(依赖注入)

    springboot成神之--ioc容器(依赖注入) spring的ioc功能 文件目录结构 lang Chinese English GreetingService MyRepository MyC ...

  4. 用Python语言设计GUI界面

    我们大家都编写过程序,但是如果能够设计一个GUI界面,会使程序增添一个很大的亮点!今天就让我们来用目前十分流行的python语言写出一个最基本的GUI,为日后设计更加漂亮的GUI打下基础. 工具/原料 ...

  5. mysql日期获取

    获取当前日期在本周的周一:select subdate(curdate(),date_format(curdate(),'%w')-1) 获取当前日期在本周的周日:select subdate(cur ...

  6. oracle xe远程访问

    oracle xe其实监听了1521端口 netstat -ano|findstr 只是没请求防火墙权限而已. 手动打开防火墙1521端口 管理员运行下面的命令 本机环境win10 netsh adv ...

  7. SKNode的渲染顺序

    [SKNode的渲染顺序] SKNode的zPosition属性,指定相对于其父视图的z轴坐标. The default value is 0.0. The positive z axis is pr ...

  8. jquery与原生js比较

    以选择符为例,类似于这种 $(".class") 方式,在ie里面,肯定比$("#id") 低很多,而对于chrome和firefox,则因为提供了getEle ...

  9. SpringSecurity3.X权限原理(转)

      这里给出一个简单的安全验证的实现例子,先说一下需求: 1.通过登录页面进行登录 2.用户登录前访问被保护的地址时自动跳转到登录页面 3.用户信息存储在数据表中 4.用户权限信息存在在数据表中 5. ...

  10. php 5.3 以上fpm安装

    安装PHP #wget http://cn2.php.net/get/php-5.3.8.tar.gz/from/cn.php.net/mirror #tar -zxvf php-5.3.8.tar. ...