===============================================
未完待续,转载时请表明出处:http://www.cofftech.com/thread-1394-1-1.html
欢迎大家跟帖讨论哈~~~~~
===============================================
如果在建立新对象时希望将同一类中原有对象内所有非静态数据的值都复制到新对象中,犹如:
int j=10;
int k=j; 或int k(j); 那样,
则C++系统本身能够完成此类简单操作。
[例1]系统为新对象复制非静态数据
#include <iostream.h>
#include <string.h>
class point {
int a, b;
char *ptr;
int size;
int arr[3];
public:
point (int j, int k, char *s, int m) {
a = j; b = k;
size = strlen(s) + 1;
ptr = new char[size];
strcpy( ptr, s);
for (int x=0; x<3; x++) arr[x] = x+m;
cout<<"Cons"<<endl;
}
void delet() { delete [ ]ptr; }
void show ( ){
cout<<a<<' '<<b<<' ';
cout << ptr << ' ';
for (int x=0; x<3; x++) cout<<arr[x]<<' ';
cout<<endl;
}
};
void main()
{
point p1(6, 9, "You", 2);
p1.show( );
point p2 = p1;
p2.show( );
point p3 (p2);
p3.show( );
p1.delet( ); // delete only once
}
/* Results:
Cons
6 9 You 2 3 4
6 9 You 2 3 4
6 9 You 2 3 4
*/
以上程序中,只在建立对象p1时调用了构造函数Cons,而在建立对象p2和p3时则不调用构造函数,只是直接将对象p1各数据成员的值复制到对象p2和p3内,从而将对象p2和p3初始化。运行结果显示,这三个对象的数据成员a、b、char*和arr[3]互相完全相同,复制成功。
由于程序只调用过一次构造函数,也即只调用一次new运算符,因此在程序结束时也只须调用一次delete运算符。据此,使用另外的函数如下:
void delet( ) { delete [ ]ptr; }
C++系统在将原有对象内所有非静态数据的值复制到新对象中时,对数据类型并无限制。不但有预定义类型,而且有用户自定义类型,例如类的对象。当对象中含有子对象时(此时该对象称为复合对象),C++系统仍能将原有对象内包括子对象在内的所有非静态数据的值复制到新对象中,见下例:
[例2] 系统为复合对象复制非静态数据。其中子类class point包含图形的端点坐标x和y,而复合类class figure还包括图形的尺寸dim。这些尺寸可用作立体图形例如立方体、立体圆等的尺寸参数。
#include <iostream.h>
class point
{
int x;
double y;
public:
point (int j, double m)
{ x = j; y = m;
cout<<"CONS-sub"<<endl; }
void sub_show( )
{ cout<<"sub-object : "<<x<<" and "<<y<<endl; }
};
class figure
{
int dim;
point sub_obj; // sub_obj为子对象
public:
figure (int a, int b, double d) : dim(a), sub_obj(b, d) //将数据和 子对象初始化
{ cout<<"CONS"<<endl; }
void show( ) {
sub_obj.sub_show( ); //显示子对象
cout<<"dim = "<<dim<<endl;
}
};
void main()
{
figure obj1(123, 456, 98.76);
cout<<"First object:"<<endl;
obj1.show( );
figure obj2 = obj1;
//将对象obj1内所有非静态数据(包括子对象sub_obj)的值复制到对象obj2中
cout<<"Second object:"<<endl;
obj2.show( );
}
/* Results:
CONS-sub
CONS
First object:
sub-object : 456 and 98.76
dim = 123
Second object:
sub-object : 456 and 98.76
dim = 123
*/
以上程序中,建立对象objp1时,先后调用了子对象和主对象的构造函数。而在建立对象objp2时,只由系统将对象objp1(包括子对象中的)的非静态数据复制到对象objp2中,并未调用构造函数。
C++系统也能将一个对象内所有非静态数据的值复制到另一对象的子对象内,见下例:
[例3]系统将对象内非静态数据的值复制到另一对象的子对象内
#include <iostream.h>
class point //用于建立子对象
{
double x;
double y;
public:
point (int j=0, double m=0)
{ x = j; y = m;
cout<<"CONS-sub"<<endl; }
void sub_show( )
{ cout<<"子对象部分: "<<x<<" and "<<y<<endl; }
};
class figure
{
public:
figure (double d) : dim(d) //将数据和子对象初始化
{ cout<<"CONS_fig"<<endl; }
void show( ) { sub_obj.sub_show( ); //显示子对象
cout<<"复合对象部分: "<<dim<<endl; }
double dim;
point sub_obj; // sub_obj为子对象
};
void main()
{
figure objf (135); //建立复合对象objf,其子对象初始化为缺省值
objf.show( );
cout<<"对复合对象objf的子对象sub_obj赋值:";
point objp (789, 123.456); //建立对象objp并初始化
objf.sub_obj = objp;
//使用对象figp对复合对象objf的子对象sub_obj赋值
objf.show( );
}
/* Results:
CONS-sub
CONS_fig
子对象部分: 0 and 0
复合对象部分: 135
CONS-sub
子对象部分: 789 and 123.456
复合对象部分: 135
*/
有些书上提到,这些数据的复制是由所谓拷贝构造函数完成的。至少在VC++ 6.0版本中这种说法不对。数据的复制操作全由系统完成,并不调用任何实际上不存在的所谓拷贝构造函数。
以前提到,只当用户在类中定义了构造函数后,建立对象时系统才调用其构造函数。但尚须提及,当系统复制对象时,并不调用构造函数。因此时系统不使用任何实参来进行初始化,而只是简单地拷贝数值。
可能会进一步提问:不同类的对象(不是子对象)之间如何复制数据?这较为复杂,需要依靠赋值运算符的重载功能,以后我们会讨论的。
未完待续,转载时请表明出处:http://www.cofftech.com/thread-1394-1-1.html
欢迎大家跟帖讨论哈~~~~~
===============================================
如果在建立新对象时希望将同一类中原有对象内所有非静态数据的值都复制到新对象中,犹如:
int j=10;
int k=j; 或int k(j); 那样,
则C++系统本身能够完成此类简单操作。
[例1]系统为新对象复制非静态数据
#include <iostream.h>
#include <string.h>
class point {
int a, b;
char *ptr;
int size;
int arr[3];
public:
point (int j, int k, char *s, int m) {
a = j; b = k;
size = strlen(s) + 1;
ptr = new char[size];
strcpy( ptr, s);
for (int x=0; x<3; x++) arr[x] = x+m;
cout<<"Cons"<<endl;
}
void delet() { delete [ ]ptr; }
void show ( ){
cout<<a<<' '<<b<<' ';
cout << ptr << ' ';
for (int x=0; x<3; x++) cout<<arr[x]<<' ';
cout<<endl;
}
};
void main()
{
point p1(6, 9, "You", 2);
p1.show( );
point p2 = p1;
p2.show( );
point p3 (p2);
p3.show( );
p1.delet( ); // delete only once
}
/* Results:
Cons
6 9 You 2 3 4
6 9 You 2 3 4
6 9 You 2 3 4
*/
以上程序中,只在建立对象p1时调用了构造函数Cons,而在建立对象p2和p3时则不调用构造函数,只是直接将对象p1各数据成员的值复制到对象p2和p3内,从而将对象p2和p3初始化。运行结果显示,这三个对象的数据成员a、b、char*和arr[3]互相完全相同,复制成功。
由于程序只调用过一次构造函数,也即只调用一次new运算符,因此在程序结束时也只须调用一次delete运算符。据此,使用另外的函数如下:
void delet( ) { delete [ ]ptr; }
C++系统在将原有对象内所有非静态数据的值复制到新对象中时,对数据类型并无限制。不但有预定义类型,而且有用户自定义类型,例如类的对象。当对象中含有子对象时(此时该对象称为复合对象),C++系统仍能将原有对象内包括子对象在内的所有非静态数据的值复制到新对象中,见下例:
[例2] 系统为复合对象复制非静态数据。其中子类class point包含图形的端点坐标x和y,而复合类class figure还包括图形的尺寸dim。这些尺寸可用作立体图形例如立方体、立体圆等的尺寸参数。
#include <iostream.h>
class point
{
int x;
double y;
public:
point (int j, double m)
{ x = j; y = m;
cout<<"CONS-sub"<<endl; }
void sub_show( )
{ cout<<"sub-object : "<<x<<" and "<<y<<endl; }
};
class figure
{
int dim;
point sub_obj; // sub_obj为子对象
public:
figure (int a, int b, double d) : dim(a), sub_obj(b, d) //将数据和 子对象初始化
{ cout<<"CONS"<<endl; }
void show( ) {
sub_obj.sub_show( ); //显示子对象
cout<<"dim = "<<dim<<endl;
}
};
void main()
{
figure obj1(123, 456, 98.76);
cout<<"First object:"<<endl;
obj1.show( );
figure obj2 = obj1;
//将对象obj1内所有非静态数据(包括子对象sub_obj)的值复制到对象obj2中
cout<<"Second object:"<<endl;
obj2.show( );
}
/* Results:
CONS-sub
CONS
First object:
sub-object : 456 and 98.76
dim = 123
Second object:
sub-object : 456 and 98.76
dim = 123
*/
以上程序中,建立对象objp1时,先后调用了子对象和主对象的构造函数。而在建立对象objp2时,只由系统将对象objp1(包括子对象中的)的非静态数据复制到对象objp2中,并未调用构造函数。
C++系统也能将一个对象内所有非静态数据的值复制到另一对象的子对象内,见下例:
[例3]系统将对象内非静态数据的值复制到另一对象的子对象内
#include <iostream.h>
class point //用于建立子对象
{
double x;
double y;
public:
point (int j=0, double m=0)
{ x = j; y = m;
cout<<"CONS-sub"<<endl; }
void sub_show( )
{ cout<<"子对象部分: "<<x<<" and "<<y<<endl; }
};
class figure
{
public:
figure (double d) : dim(d) //将数据和子对象初始化
{ cout<<"CONS_fig"<<endl; }
void show( ) { sub_obj.sub_show( ); //显示子对象
cout<<"复合对象部分: "<<dim<<endl; }
double dim;
point sub_obj; // sub_obj为子对象
};
void main()
{
figure objf (135); //建立复合对象objf,其子对象初始化为缺省值
objf.show( );
cout<<"对复合对象objf的子对象sub_obj赋值:";
point objp (789, 123.456); //建立对象objp并初始化
objf.sub_obj = objp;
//使用对象figp对复合对象objf的子对象sub_obj赋值
objf.show( );
}
/* Results:
CONS-sub
CONS_fig
子对象部分: 0 and 0
复合对象部分: 135
CONS-sub
子对象部分: 789 and 123.456
复合对象部分: 135
*/
有些书上提到,这些数据的复制是由所谓拷贝构造函数完成的。至少在VC++ 6.0版本中这种说法不对。数据的复制操作全由系统完成,并不调用任何实际上不存在的所谓拷贝构造函数。
以前提到,只当用户在类中定义了构造函数后,建立对象时系统才调用其构造函数。但尚须提及,当系统复制对象时,并不调用构造函数。因此时系统不使用任何实参来进行初始化,而只是简单地拷贝数值。
可能会进一步提问:不同类的对象(不是子对象)之间如何复制数据?这较为复杂,需要依靠赋值运算符的重载功能,以后我们会讨论的。
发表评论
-
C++主流预处理,编译和链接过程
2011-09-11 13:26 10556在C++的程序的编写过程 ... -
c++ 一个简单的链表
2011-09-11 13:13 99141 #include <stdio.h> 2 # ... -
【2011.8.2】<C++学习笔记>预处理功能
2011-08-03 12:18 1447预处理功能介绍 ... -
C++经典电子资料下载合集
2011-07-11 11:43 35341.C++ 逆向工程 pdf高清下 ... -
《C++学习笔记》静态数据成员
2011-05-20 13:15 1088=============================== ... -
《C++学习笔记》不同数据类型对象的构造函数和析构函数的调用顺序
2011-05-19 01:34 1307=============================== ... -
《C++学习笔记》子对象构造函数和析构函数的调用顺序
2011-05-19 01:34 1475=============================== ... -
《C++学习笔记》子对象的初始化
2011-05-19 01:33 1684=============================== ... -
《C++学习笔记》特定类型数据成员的初始化
2011-05-17 10:56 1252========== ... -
《C++学习笔记》析构函数(destructor)
2011-05-17 10:55 1107=============================== ... -
《C++学习笔记》带缺省参数的构造函数(constructor with default arguments)
2011-05-16 12:03 2633=============================== ... -
《C++学习笔记》构造函数及特点
2011-05-16 12:02 1267========== ... -
《C++学习笔记》【封装性】类的接口部分与实现部分的分离
2011-05-16 11:41 1587========== ... -
《C++学习笔记》【封装性】对象及其内存存储内容
2011-05-16 11:40 782========== ... -
《C++学习笔记》【封装性】成员函数的说明和定义
2011-05-16 11:37 901成员函数可在类体之内、也可在类体之外被定义。规范的做法是将成员 ... -
《C++学习笔记》【封装】封装性
2011-05-16 11:35 672以下程序依靠封装,能 ...
相关推荐
C++类与对象:static静态数据成员静态成员函数.doc
一般地,线程要读写类的私有成员变量,只有两种方法:将全局函数声明为类友元friend,或者使用静态的成员函数static。...本例就是自己的研究成果,使用非静态的成员函数作为线程函数,还能修改类的非静态的数据成员。
c++学习笔记/知识要点精华版
C++ 学习笔记C++ 学习笔记C++ 学习笔记C++ 学习笔记
c++学习笔记.pdf
C++学习笔记C++学习笔记C++学习笔记C++学习笔记C++学习笔记
C++学习笔记
内容是C++面对对象的,目录大致来源于菜鸟文档的C++面向对象,笔记是参考各种文章以及菜鸟文档改编的,内容包含C++类和对象(类定义和对象定义,类成员函数,类访问修饰符,友元函数,内联函数,this指针,静态成员...
C++学习笔记.docx
c++完美学习笔记c++完美学习笔记c++完美学习笔记c++完美学习笔记
C++学习笔记: 以学习、思考、记录、分享为乐。
【C++学习笔记】一份详细的学习笔记,让你轻松掌握C++编程!
C++ 学习笔记C++ 学习笔记C++ 学习笔记C++ 学习笔记002
C++学习笔记
编写一个类,声明一个数据成员和一个静态数据成员,让构造函数初始化数据成员,并把静态数据成员加1,让析构函数把静态成员减1。(创建三个对象,然后显示他们的数据成员和静态成员,在析构每个对象,显示结果。)
C++基础的学习笔记(其中的代码源件可私信留言) C++中的空头程序 使用C++书写hello world 学习变量 学习常量 标识符命名规则 数据类型 运算符 程序流程结构 数组 函数 指针 结构体
C++ 学习笔记C++ 学习笔记C++ 学习笔记C++ 学习笔记C++ 学习笔记003
C++ 学习笔记C++ 学习笔记C++ 学习笔记C++ 学习笔记C++ 学习笔记004
通过函数指针调用C++非静态成员函数通过函数指针调用C++非静态成员函数
C++ 学习笔记C++ 学习笔记C++ 学习笔记C++ 学习笔记001