当前位置:C++技术网 > 资讯 > 将一个类作为另一个类的成员的方法

将一个类作为另一个类的成员的方法

更新时间:2015-06-24 18:06:12浏览次数:1+次

    我们经常会将一个处理的相关函数和变量封装在一个类中,这样提高了移植性,也便于使用。但是有时候又需要使用这些函数和变量,如何处理?在不破坏原有的结构上,我们照样可以轻松处理,那就是让封装好的类作为另一个类的成员。
    为了区别,将被封装好的类成为A类,你要使用的类叫做B类。现在的目标就是将A类对象作为B类对象的成员。下面讲解实现原理和实现方法。


    第一种方法:使用对象成员。
    这种方法很常用,但是有些地方要注意。对于初学者来说,还是不好理解,也不知道如何使用。下面来讲讲。
    首先,要将A类的对象作为B类的成员,你必须在B类声明前声明A类。这样,在B类声明中,就知道A类是一个类,不然编译器是不知道A这个字母代表什么,只有在B类声明前声明了A类,B类中就知道A代表的是一个类,是一种自定义类型。要达到这个效果,需要在B类声明前,包含A类的头文件,A类的头文件中就是A类的声明,有A类的数据成员,也有成员函数等。
    其次,就是像声明一个成员变量一样,在B类中添加一个成员,如A m_a; 这句表示使用A类声明了一个B类的成员变量m_a。但是在此,只是对m_a成员变量声明而已,并没有分配内存空间,具体的声明定义和初始化等,请阅读《C/C++声明定义初始化和赋值独家剖析深刻理解》。
    然后,就是初始化m_a。因为这个成员是一个类对象,因此需要调用构造函数才能初始化。因为这个对象m_a在B类中,m_a对象的构造必然是在B类对象构造之前进行,因此不能在B类构造函数中进行,又因为m_a不是全局对象,也不能在函数外部。如何解决这个问题呢?这就是C++提出的成员初始化列表,用来解决这类问题的。成员初始化列表的使用,请参考本站其他相关文章。如果A类提供了默认构造函数,不需要参数的,那就不需要显式初始化,让编译器自动完成即可,但是有时候需要在构造时就需要传值,此时就只能通过成员初始化列表。
    最后,这个m_a的使用,就可以成员变量一样使用,没有特别的。
代码如下:


class A
{
public:
   int a;
public:
    void testA();
};

class B
{
public:
   int b;
    A a;//使用对象成员。
public:
    void testB(){}
};


    第二种方法:使用对象指针。
    这种方法比较便捷,省去了初始化的麻烦,且可以动态的创建对象,但是也会带来内存的使用问题。初学者推荐使用第一种方法。指针的使用,需要一定功底,如果使用不当,会出现内存访问违规或者内存泄露问题。指针的深入理解,请参考《带你深入理解指针,轻松掌握指针》。
    首先,在B类声明前,包含A类头文件,这个第一个方法的是一样的解释,即使是声明指针,也要包含,因为要使用A代表一个类,就必须先包含A类头文件告诉编译器A是一个类的代名词而不是简单的字符。
    其次,声明A类指针作为成员,如A * pA;这样就可以声明了。很简单,这个指针和普通指针一样大,并不占用很多内存。在很多要动态创建很多对象时特别方便。用完就释放,需要就创建。
    然后,就是初始化指针。在B类构造函数中,初始化时将这个指针设为NULL。这是规范的写法,之后创建对象后便指向了对象,此时指针就不是NULL了,删除指针指向的对象后,一定要将指针值设置成NULL。这样,要判断指针是否指向一个对象,就只要判断指针是否为NULL即可。
    最后,在使用时,需要A类对象时,new一个A类对象,然后赋值给pA ,这样pA就指向了new出来的对象,然后都用指针来操作A。用完后,使用delete pA 。
    
    特别说明:为了防止内存泄露,new了对象后,一定要delete 这个对象。最容易出现内存泄露的就是频繁的new对象和delete对象,导致前一个指向的对象没有删除就new了一个新对象给指针,最后之前的对象就无法使用,知道程序结束才能被释放,这就是内存泄露了哦。

    正确的代码写法如下:

if(pA/* != NULL*/)//此处需要初始化时设置指针为空。
{
    delete pA;
    pA = new A;
}else
{
    pA = new A;
}

使用对象指针作为成员的代码如下:
代码如下:

class A
{
public:
   int a;
public:
    void testA();
};

class C
{
public:
   int c;
    A * pA;//使用对象指针。
public:
    void testC(){}
};