类占用内存大小:——深入理解C++对象模型
类所占内存的大小是由成员变量决定的,静态变量除外,成员函数不计算在内。
class CBase
{
};
sizeof(CBase)=1;
class CBase
{
int a;
char p;
};
sizeof(CBase)=8;
class CBase
{
public:
CBase(void);
virtual ~CBase(void);
private:
int a;
char *p;
};
再运行:sizeof(CBase)=12
记得对齐的问题。int 占4字节//注意这点和struct的对齐原则很像
(四)
class CChild : public CBase
{
public:
CChild(void);
~CChild(void);
virtual void test();
private:
int b;
};
输出:sizeof(CChild)=16;
可见子类的大小是本身成员变量的大小加上父类的大小。
总结:
空的类是会占用内存空间的,而且大小是1,原因是C++要求每个实例在内存中都有独一无二的地址。
(一)类内部的成员变量:
普通的变量:是要占用内存的,但是要注意对齐原则(这点和struct类型很相似)。
static修饰的静态变量:不占用内容,原因是编译器将其放在全局变量区。
(二)类内部的成员函数:
普通函数:不占用内存。
虚函数:要占用4个字节,用来指定虚函数的虚拟函数表的入口地址。所以一个类的虚函数所占用的地址是不变的,和虚函数的个数是没有关系的。
c++变量的声明和定义区别:
①变量定义:用于为变量分配存储空间,还可为变量指定初始值。程序中,变量有且仅有一个定义。
②变量声明:用于向程序表明变量的类型和名字。
③定义也是声明:当定义变量时我们声明了它的类型和名字。
④extern关键字:通过使用extern关键字声明变量名而不定义它。
程序设计风格:
1. 不要把变量定义放入.h文件,这样容易导致重复定义错误。
2. 尽量使用static关键字把变量定义限制于该源文件作用域,除非变量被设计成全局的。
3. 可以在头文件中声明一个变量,在用的时候包含这个头文件就声明了这个变量。
strcpy与memcpy:
区别:
1、strcpy只能拷贝char*类型变量,memcpy可以拷贝任意类型,例如字符数组、整型、结构体、类等;
2、strcpy遇到被复制字符串的”\0"才结束,所以如果 dst 的空间不够,会引起 buffer overflow。memcpy并不是遇到'\0'就结束,而是一定会拷贝完n个字节。
3、注意:memcpy没有考虑内存重叠的情况,所以如果两者内存重叠,会出现错误。
使用方法:
1、strcpy(char* dst, const char* src);
string str = "0123456789";
string str1;
strcpy(const_cast<char*>(str1.c_str()), str.c_str());
cout << str1.c_str();
结果:"0123456789"
2、void *memcpy(void*dest, const void *src, size_t n);
由src指向地址为起始地址的连续n个字节的数据复制到以destin指向地址为起始地址的空间内。
函数返回一个指向dest的指针。
char str[3] = "01"; // 定义字符数组大小的时候记得加上"\0"
char str1[3];
memcpy(str1, str, 3); // 拷贝字节数n = strlen(str)+1
cout << str1;
输出:01
strlen与sizeof:
1、说明
在C++里应包含头文件#include <cstring>
strlen是一个函数,参数应为char*类型,不可以为string类型。表示的是计算字符数组中有效元素的长度或个数,注意不包含"\0"在内。
char* str1 = "abcd";
cout << strlen(str1);
结果为:4
2、与sizeof的区别
(1)sizeof()返回的是变量声明后所占的内存数,不是实际长度;如:
char str[20]="0123456789";
cout << "strlen:" << strlen(str) << endl;
cout << "sizeof:" << sizeof(str) << endl;
结果:
strlen:10
sizeof:20
(2)sizeof是操作符(关键字),strlen是函数;
(3)sizeof可以用类型做参数,strlen只能用char*做参数,且必须是以’’\0’'结尾的;