目录
2.1 C++对象的内存模型
直接看代码:
#include <iostream>
#include <string.h>
using namespace std;
class Test
{
public:
int m_i;
char m_c;
int m_n;
Test(){};
~Test(){};
};
int main()
{
Test T;
cout << sizeof(T) << endl;
return 0;
}
运行结果:
12
从上面可以看出,对象的大小为成员变量总的大小,int占用4字节, char由于内存对齐也占用4字节,一共12字节。对象的大小只与成员变量有关,和成员函数没有关系。将main函数修改一下:
int main()
{
Test T;
memset((void *)&T, 0, sizeof(T));
T.m_i = 12;
T.m_c = 20;
T.m_n = 33;
int *pTest = (int *)&T;
cout << *pTest << endl;
pTest++;
cout << *pTest << endl;
pTest++;
cout << *pTest << endl;
return 0;
}
运行结果:
12
20
33
这说明C++的对象的内存分布是和成员变量相关的,假如对象的起始地址(即上述程序的&T)为0x10000,那么该对象的内存分布如下图所示:
2.2 const成员变量和成员函数
2.2.1 const成员变量
const成员变量的用法和普通的const变量用法类似, 只需要再声明时加上const关键字,初始化const成员变量只有一种方法,就是通过参数初始化表。
2.2.2 const成员函数
const成员函数可以使用类中的所有成员变量,但是不能修改它们的值。这种措施主要是为了保护数据而设置的。const成员函数也称为常成员函数。
常成员函数需要在声明和定义的时候在函数头部的结尾加上const关键字,如:
class Test
{
public:
char *m_name;
char* getname() const;
}
char *Test::getname() const
{
//m_name = "hello"; 错误,编译器会报错
return m_name;
}
int main()
{
Test T;
T.getname();
return 0;
}
2.2.3 const对象
const 也可以用来修饰对象,称为常对象。一旦将对象定义为常对象之后,就只能调用类的 const 成员了。
定义常对象的语法和定义常量的语法类似:
const class object(params);
class const object(params);
当然也可以定义 const 指针:
const class *p = new class(params);
class const *p = new class(params);
class为类名,object为对象名,params为实参列表,p为指针名。两种方式定义出来的对象都是常对象。
一旦将对象定义为常对象之后,不管是哪种形式,该对象就只能访问被 const 修饰的成员了(包括 const 成员变量和 const 成员函数),因为非 const 成员可能会修改对象的数据(编译器也会这样假设),C++禁止这样做。
2.3 友元
友元就是用来控制访问一个类中的private成员的。
2.4 string类的常用方法
string s
- s.length(), 返回字符串的真是长度,不包括结尾的‘\0’。
- s.c_str(), 返回字符串的const指针const char *。
- s[i], 返回字符串中第i个字符,从0开始。
- s.find(),等等