C++对象数组作为类成员的问题

来源:互联网 发布:流浪的蛤蟆 知乎 编辑:程序博客网 时间:2024/05/17 23:53
例如:
class ObjectB{};

class ObjectA{
public:
    ObjectB array[5];//对象数组作为类的成员
}

那样的话对象数组的初始化会变得很麻烦,
因为数组名不能作为左值,所以不可以指针传递的方式赋值。
而且不能通过参数列表(构造函数后面加一个冒号)的方式初始化,
所以只能让类ObjectA自动调用类ObjectB的无参构造函数.
---------------
#include <iostream.h>
#include 
"stdlib.h"
class   ObjectB{
public:
    
int a;
public:
    ObjectB(
int m=0)
    
{
        a
=m;
    }

}
;
class   ObjectA
public:
        ObjectB   Array[
5]; 
public
        ObjectA(
int   *p)
        
{
            Array[
0]=ObjectB(p[0]);
            Array[
1]=ObjectB(p[1]);
            Array[
2]=ObjectB(p[2]);
        }
 
}
;

int main()
{
    
int p[5]={0,2,2,3,4};
    ObjectA am
=ObjectA(p);
    cout
<<am.Array[1].a<<endl;
    
return 0;
}

---------------

我们可以使用替代方式:
class A{};

classB{
public:
    A*a;//A类型的指针作为类的成员
}
同样带来很大的问题,
(1)浅拷贝,深拷贝的问题,除非重载拷贝构造函数,类B才能实现深拷贝,因为成员中有指针,所以无法简单的用拷贝构造函数生成一个新对象,而用无参构造函数生成的新对象也会有问题,因为里面的指针一般都默认为NULL了。

重载拷贝构造函数的时候需要申请一定长度的内存,将拷贝对象的指针所指向的空间拷贝到新申请的空间,再进行操作。注意申请后要释放。
一个拷贝构造函数的例子
SparseMatrix::SparseMatrix(const SparseMatrix&s)
    
{
      Rows
=s.Rows;
   Cols
=s.Cols;
   Count
=s.Count;
   smArray
=new Trituple[6];
//此处还需要复制对象
    }


----------------------
补充知识:
------------------http://www.ksarea.com/articles/20070829_memory-partition-stack-heap-difference.html

C/C++应该是大学里最先接触的编程语言,它们的重要性不言而喻。但是我始终抱着“数组名就是指针”的错误信条到现在,可能是因为大学老师错误的讲解使我一直保留着这种误解。指针是C/C++语言的特色,而数组名与指针有太多的相似,甚至很多时候,数组名可以作为指针使用,所以也难免在学习中将两者混淆。这里介绍下指针和数组名的区别:

1.指针和数组名占据的内存空间大小不一样,如下程序1:

char str[10];
char *pstr=str;
cout<<
cout<<sizeof

第一行输出结果是:10,第二行输出结果是:4

从这里我们可以看出:数组名对应着(而不是指向)一块内存(数组所占的内存区域)或者说是指代数组这种数据结构,其地址与容量在生命期内保持不变,只有数组的内容可以改变。指针对应着一个占据4个字节(Win32)的内存区域,而指向这4个字节所存储的地址所对应的内存单元,它可以指向任意类型的内存块。因此,sizeof(str)值为数组占据的内存空间大小即10个字节,而sizeof(pstr)值为指针的值占据的内存空间大小即4个字节。

2.数组名不是指针,但是在一定的情况下转换为指代数组的首地址的指针,而这个数组名转为的指针只能是指针常量。
在以下两种情况下才能进行这种转换:
a.在程序1第二行代码中,将数组名直接赋值给指针,此时数组名转换为指向数组的首单元的常量指针。
b.直接将数组名作为指针形参的时候,数组名则转换为指向数组的首单元的常量指针进行传递,如下程序2:

void fun(char str[])
{
cout<<
str++;
}
void main()
{

char str1[5];
fun(str1);

}

注意:数组名作为函数形参进行传递时,在子函数体内,它已经不再是一个指针常量,而是变成一个真正的指针,可以进行增减等操作,可以被修改。所以程序2中子程序第一条语句输出的sizeof(str)的值为4.

既然数组名可以被看作指针常量,而常量是不能修改的,那么如下代码是不允许的:

char str[10];
str++;

但如下代码则合法的:

char str[10];
char *pstr=str;
pstr++;

3.使用指针访问数组和使用数组名访问数组本质不同。
例如:

char str[7]=”ksarea”;
char *pstr=str;
cout<<<


其中str[3]和pstr[3]返回的都是字符’r',但是编译器产生的执行代码却不一样。对于str[3],执行代码是从str开始,向后移动两个字节,然后取出其中的字符;而对于pstr[3],执行代码是从pstr中取出地址,然后在其上加3,然后取出对应内存中的字符。当然,如果pstr是指向int型的指针,那么pstr[3]的处理过程是从pstr中取出地址,然后在其上加上3*sizeof(int),最后取出对应内存中的字符,其他的数据类型一次类推。
原创粉丝点击