1、new当个对象new在自由空间分配内存,但其无法为其分配的对象命名,因次是无名的,分配之后返回一个指向该对象的指针。
int
*p =
new
int
;
// pi
指向一个动态分配的,未初始化的无名对象
此new表达式在自由空间构造一个int类型对象,并返回指向该对象的指针。
默认情况下,动态分配的对象是默认初始化的,这意味着内置类型或组合类型的对象的值是无定义的,而类类型对象将用默认构造函数进行初始化。
2、new(多个对象)数组
new分配的对象,不管单个对象还是多个对象的分配,都是默认初始化。但可以对数组进行值初始化,方法就是:在大小之后添加一对空括号。
int
*p
1
=
newint
[
10
];
// 10
个未初始化
int
int
*p2 =
newint
[
10
]();
// 10
个值初始化为
0
的
int
int p3[10];//为初始化随机值
cout<<p1[0]<<" "<<p1[1]<<endl;
cout<<p2[0]<<" "<<p2[1]<<endl;
cout<<p3[0]<<" "<<p3[1]<<endl;
总结:
对于内置类型而言,new仅仅是分配内存,除非后面显示加(),相当于调用它的构造函数,对于自定义类型而言,只要一调用new,那么编译器不仅仅给它分配内存,还调用它的默认构造函数初始化,即使后面没有加()
#include <QCoreApplication>
#include <iostream>
using namespace std;
struct A { int m; }; // POD
struct B { ~B(){}; int m; }; // non-POD, compiler generated default ctor
struct C { C() : m() {}; ~C(){}; int m; }; // non-POD, default-initialising m
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
A *aObj1 = new A;
A *aObj2 = new A();
cout << aObj1->m << endl;
cout << aObj2->m << endl;
B *bObj1 = new B;
B *bObj2 = new B();
cout << bObj1->m << endl;
cout << bObj2->m << endl;
C *cObj1 = new C;
C *cObj2 = new C();
cout << cObj1->m << endl;
cout << cObj2->m << endl;
delete aObj1;
delete aObj2;
delete bObj1;
delete bObj2;
delete cObj1;
delete cObj2;
getchar();
return a.exec();
}
#include <QCoreApplication>
#include <iostream>
using namespace std;
//#pragma pack(push)
//#pragma pack(4)
class CTest
{
public:
CTest():m_chData('\0'),m_nData(0)
{}
virtual void mem_fun(){}
virtual void mem_fun2(){}
private:
char m_chData;
int m_nData;
static char s_chData;
};
char CTest::s_chData='\0';
//#pragma pack(pop)
class CBase
{
public:
CBase() {}
};
class CBase1
{
public:
CBase1(void);
virtual ~CBase1(void);
private:
int a;
char *p;
};
class Mon
{
public:
Mon() {}
};
class Tue
{
public:
Tue() {}
};
class Wed:public Mon
{
virtual void fun()=0;
};
class Thu:public Tue,public Wed
{
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
int *p;
char *pa;
cout<<"sizeof(char)"<<sizeof(char)<<endl;
cout<<"sizeof(int)"<<sizeof(int)<<endl;
cout<<"sizeof(long)"<<sizeof(long)<<endl;
cout<<"sizeof(long long)"<<sizeof(long long)<<endl;
cout<<"sizoef(*p)"<<sizeof(p)<<endl;
cout<<"sizoef(*pa)"<<sizeof(pa)<<endl;
cout<<"sizeof class CTest:"<<sizeof(CTest)<<endl;
cout<<"sizeof (CBase):"<<sizeof(CBase)<<endl;
cout<<"sizeof(CBase1):"<<sizeof(CBase1)<<endl;
cout<<"sizeof(Mon)"<<sizeof(Mon)<<endl;
cout<<"sizeof(Tue)"<<sizeof(Tue)<<endl;
cout<<"sizeof(Wed)"<<sizeof(Wed)<<endl;
cout<<"sizeof(Thu)"<<sizeof(Thu)<<endl;
getchar();
return a.exec();
}
总结:
空的类是会占用内存空间的,而且大小是1,原因是C++要求每个实例在内存中都有独一无二的地址。
(一)类内部的成员变量:
普通的变量:是要占用内存的,但是要注意对齐原则(这点和struct类型很相似)。
static修饰的静态变量:不占用内容,原因是编译器将其放在全局变量区。
(二)类内部的成员函数:
普通函数:不占用内存。
虚函数:要占用4个字节,用来指定虚函数的虚拟函数表的入口地址。所以一个类的虚函数所占用的地址是不变的,和虚函数的个数是没有关系的。
一般情况:
32位编译器:
char :1个字节
char*(即指针变量): 4个字节(32位的寻址空间是2^32, 即32个bit,也就是4个字节。同理64位编译器)
short int : 2个字节
int: 4个字节
unsigned int : 4个字节
float: 4个字节
double: 8个字节
long: 4个字节
long long: 8个字节
unsigned long: 4个字节
64位编译器:
char :1个字节
char*(即指针变量): 8个字节
short int : 2个字节
int: 4个字节
unsigned int : 4个字节
float: 4个字节
double: 8个字节
long: 8个字节
long long: 8个字节
#pagma pack(2)
classA
{
inti;
unionU
{
charbuff[13];
inti;
}u;
voidfoo() { }
typedefchar* (*f)(void*);
enum{red, green, blue} color;
}a;
int i占4个字节
union U实例化为u占取16个字节(char数组占13个字节,但因为最大类型为int,所以占取只能为4字节的整数倍即最小16字节)
空函数不占取字节
未实例化指针不占取字节
枚举类型占取4个字节
总共占取4+16+4=24个字节
加#pragam pack(2)的话:
4+14+4=22字节