首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

C++对象数组的宣言和初始化

2013-10-14 
C++对象数组的声明和初始化我想声明一个对象数组,然后在函数中再分别初始化。现在的问题是不知道怎么初始化

C++对象数组的声明和初始化
我想声明一个对象数组,然后在函数中再分别初始化。现在的问题是不知道怎么初始化,请教高手该怎么办?急急 C++? 对象数组
[解决办法]
初始化?对象?那不就是用构造函数么……不过是个数组而已,数组不过是多个同类型数据的集合而已……你可以写个循环,然后写个带参数的构造函数,或是像上面那位说的,重载new操作符
[解决办法]
C++11支持了吧
[解决办法]
需要一个元素一个元素赋值,或者用
memcpy(dest, src, size);

[解决办法]
1、数组类型一旦声明,将自动调用默认构造函数初始化各个对象
2、一旦初始化之后,之后的只能是赋值
3、可以用 vector<T> 来声明容器,代替数组
4、可以用 allocator<T> 分配内存空间,然后用 allocator<T>::construct() 或 placement new 初始化,将内存分配与初始化分开 这一部分详见 《C++ primer 4th Edition P632 优化内存分配》
[解决办法]
这一直是个麻烦事。。。
[解决办法]
这种情况还是建议用STL里的数据结构。
默认的直接写编译器内置数组方式的定义仅支持定义的时候就完成初始化(后面再改内容就叫赋值而不是初始化了,达不到目的)。
placement new建议尽量少用或不用。除非你本来就是开发库代码。因为如果要用placement new,也得用placement delete,而且对象的生存期编译器就不再负责了,得你自己手动管理。而且placement new涉及的输入地址并不是能随意给的,一般要预先对齐,对齐边界得根据你new时候的对象的类型临时的给定。那这样看的话还不如干脆用stl的vector或者array模板得了,因为期间涉及到的数组元素处理的相关代码就算你不用stl而是自己写,功能上都差不多,但是对于不同的对象类型又不能通用,等于是需要自己一遍又一遍的实现功能上类似stl的代码。临时写的作品和别人几年专门针对性的维护的东西相比,哪个更好?不说自明的

[解决办法]
这是我写的一个程序,有对象数组
#include<iostream.h>
class Book{
public:
void input(int x)
{
qu=x;
price=10*qu;
}
void product()
{
cout<<"qu*price="<<qu*price<<endl;
}
private:
int qu,price;
};

 int main()
 {
 Book A[5];
 int i;
 for(i=0;i<5;i++)
 {
 A[i].input(i+1);
 A[i].product();
 }
 return 0;
 }

[解决办法]
在对象声明里写个init()函数,随后一个个的调用.
[解决办法]
用 allocator<T> 
[解决办法]
可以这样来


#include <iostream>

class A
{
private :
    int _n;
public:
    A( int n):_n(n) {}
};

int main()
{
    A *pA = (A*) operator new (sizeof(A) * 10);
    for(int i = 0; i != 10; ++i)
    {
        new (pA + i) A(i);
    }
}


[解决办法]
给类写一个initialize函数
[解决办法]
引用:
可以这样来

#include <iostream>

class A
{
private :
    int _n;
public:
    A( int n):_n(n) {}
};

int main()
{
    A *pA = (A*) operator new (sizeof(A) * 10);
    for(int i = 0; i != 10; ++i)
    {
        new (pA + i) A(i);
    }
}


默认的对齐是4(32位下),但是有可能A要求8字节的对齐(比如其中含有long long数据成员)。这时候这个new返回的地址经常不能满足
[解决办法]
引用:
Quote: 引用:

可以这样来

#include <iostream>

class A
{
private :
    int _n;
public:
    A( int n):_n(n) {}
};

int main()
{
    A *pA = (A*) operator new (sizeof(A) * 10);
    for(int i = 0; i != 10; ++i)
    {
        new (pA + i) A(i);
    }
}


默认的对齐是4(32位下),但是有可能A要求8字节的对齐(比如其中含有long long数据成员)。这时候这个new返回的地址经常不能满足

类对象本身就内存对齐了,管返回地址,何事呀!!
[解决办法]
引用:

Quote: 引用:

Quote: 引用:

可以这样来

#include <iostream>

class A
{
private :
    int _n;
public:
    A( int n):_n(n) {}
};

int main()
{
    A *pA = (A*) operator new (sizeof(A) * 10);
    for(int i = 0; i != 10; ++i)
    {
        new (pA + i) A(i);
    }
}


默认的对齐是4(32位下),但是有可能A要求8字节的对齐(比如其中含有long long数据成员)。这时候这个new返回的地址经常不能满足

类对象本身就内存对齐了,管返回地址,何事呀!!

想太多了。我说的对齐是整个对象的起始地址
要知道对齐的根本目的是为了让处理器取值(单个整型)的时候能一条指令整个的取。
这样就需要类或结构体每个成员都对齐。而这种保证需要同时满足成员对对象基地址的对齐和整个对象基地址本身的对齐,如果后者不满足的话其实还是算没有对齐的。

[解决办法]
operator new (sizeof(A) * 10) 不带类型的分配(sizeof(A)里面的A是不会反映到new的类型的,仅仅代表了大小信息),其实等同于 new BYTE [sizeof(A) * 10];默认的对象对齐以字节类型为准而不是待分配的类类型要求的基址对齐方式
[解决办法]
引用:
operator new (sizeof(A) * 10) 不带类型的分配(sizeof(A)里面的A是不会反映到new的类型的,仅仅代表了大小信息),其实等同于 new BYTE [sizeof(A) * 10];默认的对象对齐以字节类型为准而不是待分配的类类型要求的基址对齐方式

不对吧,sizeof(A)本身的大小,就已将对齐考虑在内了
[解决办法]
std::vector/std::array
[解决办法]
如果你定义的数组的对象类型有默认构造函数,那么恭喜你,在数组用到的时候初始化自动完成;
如果没有的话,比如有一个单参数的构造函数,那么你必须显式调用。比如
class A
{
   private: 
      int a;
   public:
      A(aa):a(aa){}
};

A arr[2] = { A(1), A(2) };
希望对你有所帮助

[解决办法]
引用:
Quote: 引用:

operator new (sizeof(A) * 10) 不带类型的分配(sizeof(A)里面的A是不会反映到new的类型的,仅仅代表了大小信息),其实等同于 new BYTE [sizeof(A) * 10];默认的对象对齐以字节类型为准而不是待分配的类类型要求的基址对齐方式

不对吧,sizeof(A)本身的大小,就已将对齐考虑在内了

sizeof(A)只是一个整数了。不会决定new返回的指针的对齐。比如下面这个例子

#include <iostream>
 
class A
{
private :
    long long _n;
public:
    A( long long n):_n(n) {}
};
 
int main()
{
    A *pA = (A*) operator new (sizeof(A) * 10);
    for(int i = 0; i != 10; ++i)
    {
        new (pA + i) A(i);
    }
}

sizeof(A)等于8,这样new执行的时候相当于
operator new (80);
而他的返回值在32位系统中默认对齐为4,也就是整个new在你强制转换成A*之前的返回值是被4整除的,实际上按语法看的话甚至有可能仅是1,也就是完全不考虑对齐。而A对象要求以8为整个对象的对齐,也就是整个new在你强制转换成A*之前的返回值能被8整除。如果是new A的话,(void *)new A的结果保证能被8整除而如果系统找不到这样的空闲地址区域的话宁可失败,而不是返回一个没有对齐的地址。而这样的约束对于(void *)operator new (80);却并不成立。
你说的A“已经考虑了对齐”其实应该指的仅是成员相对于对象基址的对齐,也就是说如果A是这样的:
class A
{
  char m1;
  int m2;
};
那么在m1到m2之间会有诺甘个字节的空缺(共sizeof(int)-1个字节)而不是让m2紧挨着m1存放。
但是涉及到内存分配,不管是直接定义也好还是用new分配,不光需要你说的这种对齐,而且还需要整个对象的基地址的对齐。这样才能最终做到每个成员在运行时真正的对齐。如果是直接定义或者用new类型的分配方式,这总是可以保证;但是去掉类型信息分配的话就没有这种保证了
[解决办法]
还有A本身的大小问题,大小对齐正是为了在定义数组的时候不至于存在部分数组元素没有对齐的问题。比如
class A
{
  char m1;
  int m2;
  char m3;
};
如果是为了压缩空间,完全可以让sizeof(A)等于9。但是这样一来如果定义A a[4];的话将会出现除了a[0]其余元素都未有对齐的情况。所以A的末尾也补一些字节从而让sizeof(A)等于3个int的字节大小

热点排行