1 编写类String的构造函数、析构函数和赋值函数
class String { public: String(Const char *str = NULL);//普通构造函数 String(const String &other); //拷由构造函数 ~String(void); //析构函数 String &operate = (const String &other);//赋值函数 private: char *m_data;//用于保存字符串 };
编写如下:
//String的析构函数 String::~String(void) { delete[] m_data;//由于m_data是内部数据类型,也可以写成delete m_data; } //String的普通构造函数 String::String(const char *str) { If(str == NULL) { m_data = new char[1]; *m_data = ‘\0′; } else { int length = strlen(str); m_data = new char[length + 1]; strcpy(m_data,str); } } //拷贝构造函数 String::String(const String &other) { int length = strlen(other.m_data); m_data = new char[length + 1]; strcpy(m_data,other.m_data); } //赋值函数 String&String::operate=(const String&other) { //1.检查自赋值 If(this == &other)\ return *this; //2.释放原有的内存资源 Delete[] m_data; //3.分配新的内存资源,并复制内容 int length = strlen(other.m_data); m_data = new char[length+1]; strcpy(m_data,other.m_data); return *this;
2 下面输出什么
main() { int a[5] = {1,2,3,4,5}; int *ptr = (int *)(&a+1); printf(“%d,%d”,*(a+1),*(ptr-1)); }
答案:输出:2,5
剖析:
-
*(a+1)就是a[1],*(ptr-1)就是a[4],执行结果是2,5;
&a+1不是首地址+1,系统会认为加一个a数组的偏移,是偏移了一个数组的大小(本例是5个int)
int *ptr = (int *)(&a+1);则ptr实际是&(a[5]),也就是a+5
原因如下:
&a是数组指针,其类型为int(*)[5];
而指针加1要根据指针类型加一定的值,不同类型的指针+1之后增加的大小不同,a是长度为5的int数组指针,所以要加5*sizeof(int)
所以ptr实际是a[5]
但是ptr与(&a+1)类型是不一样的(这点很重要)
所以ptr-1只会减去sizeof(int*)
a,&a的地址是一样的,但意思不一样,a是数组首地址,也就是a[0]的地址,&a是对象(数组)首地址,a+1是数组下一元素的地址,即a[1],&a+1是下一个对象的地址,即a[5].