假设我们有一个类A,另外一个类B中有个成员数据是A的对象,我们如何来定义这个成员数据呢?
最直接的,我们可以就把它定义为A的对象:A a_obj;
其次,我们可以把它定义为A对象的引用:A& a_obj; 或者const引用:const A& a_obj;
再者,我们还可以把它定义为A对象的指针:A* pA_obj; 或者const对象的指针:const A* pA_obj;
当我们直接使用A对象的时候,a_obj会在B对象建立的时候建立,在B销毁的时候销毁。因为这是一个新建立的对象,所以在成员初始化的时候是真正构造了对象,即我们前面说到的使用了复制构造函数。
如果使用的是A对象的引用或者指针,a_obj(或pA_obj)都没有构造新的对象。我们假设B的一个构造函数是这样的:B(const A& a_obj): a_obj(a_obj) {},那么毫无疑问,这个构造函数是能正常工作的,也就是说,我们用现成的对象,或者说是在B对象生命周期内都会一直存在的A对象去构造B对象是没有问题的。但是,如果一个构造函数是这样的:B(int a): a_obj(A(a)) {},这个函数,一般在编译的时候是不会报错或者发出警告的,但是我们分析一下,A(a)是临时构造了一个A对象,然后a_obj成为了这个临时对象的引用。但是问题是,这个临时对象在B对象构造之后就马上销毁了,也就是说,a_obj引用了一个不存在的对象(换到指针说就是指向了空指针)。这是一个巨大的错误,将在运行时引发错误。
所以,结论是:如果成员数据使用(新)对象,则必须定义这个对象所属类的复制构造函数;如果使用的是对象引用或者指针,则一定只能用已经存在并且会在B对象整个生命周期内都存在的A对象来构造这个B对象。
说得貌似很复杂,留个作为例子的3个类,大家可以多写几个演示程序试试。
#ifndef A_HPP
#define A_HPP
#include <iostream>
using namespace std;
char* get_point(int lenth);
void free_point(char* temp);
class A
{
private:
//
protected:
char* temp;
int lenth;
A();
public:
A(const A& copy);
~A();
void show() const;
};
class C: public A
{
public:
C(int _lenth);
~C();
};
class B
{
private:
A b;
public:
B(const A& a);
B(int _lenth);
~B();
void show() const;
};
#endif
#include "a.hpp"
A::A(): temp(0),lenth(0)
{
cout<< "A Constructor!" << endl;
}
A::A(const A& copy): lenth(copy.lenth)
{
temp = get_point(lenth);
cout << "A Copy Constructor" << endl;
cout << "temp at: " << int(temp) << endl;
}
A::~A()
{
cout << "temp at: " << int(temp) << endl;
free_point(temp);
cout << "Heap Deleted!\n";
cout << "A Destroyed!" << endl;
}
void A::show() const
{
cout << temp << endl;
}
//***************************************
C::C(int _lenth): A()
{
lenth = _lenth;
temp = get_point(lenth);
cout<< "C Constructor!" << endl;
cout << "temp at: " << int(temp) << endl;
}
C::~C()
{
cout << "C Destroyed!" << endl;
}
//***************************************
B::B(const A& a): b(a)
{
cout<< "B Constructor!" << endl;
}
B::B(int _lenth): b(C(_lenth))
{
cout<< "B Constructor!" << endl;
}
B::~B()
{
cout << "B Destroyed!" << endl;
}
void B::show() const
{
b.show();
}
//************************************
char* get_point(int lenth)
{
char* temp = new char[lenth+1];
for ( int i = 0; i< lenth; i++ )
temp[i] = '*';
temp[lenth] = '\0';
cout << "New buffer got!\n";
return temp;
}
void free_point(char* temp)
{
delete []temp;
cout << "Buffer deleted!\n";
}
posted on 2008-04-14 12:36
lf426 阅读(502)
评论(0) 编辑 收藏 引用 所属分类:
语言基础、数据结构与算法