下半年要找工作了,作为一个技术不牛、代码能力弱的小硕,表示很揪心,也为自己的编码能力深深的汗颜,也许自己并不太适合程序猿这个工作吧!
Anyway, 还是要好好复习和学习的,尤其是要锻炼自己的编码能力,希望可以找到理想的工作。希望可以通过记录博客来鞭策自己好好复习。
不管未来工作如何,掌握基础的专业知识,也是对一年后要结束的学生生涯的一个交代吧!fighting~~~
看书提供的代码,发现自己有这几个问题还没有搞明白。
1. _tmain和main的区别
_tmain()是windows提供的对unicode字符集和ANSI字符集进行自动转换用的程序入口点函数。是main的一个别名,在<stdafx.h>中有宏定义,即
#include <stdio.h> #include <tchar.h>,其中头文件<tchar.h>中有它的宏定义:
#define _tmain main
预编译后,_tmain变成了main.
main()是标准C++函数入口,默认字符编码格式ANSI。
2.P24. 面试题1. 赋值运算符函数
#include <iostream>
#include <string>
using namespace std;
class CMyString
{
public:
CMyString(char* pData=NULL);
CMyString(const CMyString& str);
~CMyString(void);
//声明返回值的类型为引用,才能允许连续赋值
CMyString& operator = (const CMyString& str);
void Print();
private:
char* m_pData;
};
CMyString::CMyString(char *pData)
{
if (pData == NULL)
{
m_pData = new char[1];
m_pData[0] = '\0';
}
else
{
int length = strlen(pData);
m_pData = new char[length + 1];
strcpy(m_pData, pData);
}
}
CMyString::~CMyString()
{
delete[]m_pData;
}
CMyString::CMyString(const CMyString& str)
{
int length = strlen(str.m_pData);
m_pData = new char[length + 1];
strcmp(m_pData, str.m_pData);
}
CMyString& CMyString::operator=(const CMyString& str)
{
/*
* 1.普通写法
if (this == &str)
return *this;
delete[]m_pData;
m_pData = NULL;//释放内存
m_pData = new char[strlen(str.m_pData) + 1];//若内存不足则会导致new char抛出异常,m_pData会是空指针
strcpy(m_pData, str.m_pData);
return *this;*/
/*
* 2.考虑异常安全性写法,先创建临时实例,在交换临时实例和原来的实例
* 然而运行结果并不太对。。输出的有问题。。????感觉这个有点问题。
if (this != &str)
{
CMyString strTemp(str);
// 需要交换,因为对象的两个实例空间上不能有交集
char * pTemp = strTemp.m_pData;
strTemp.m_pData = m_pData;
m_pData = pTemp;
}
return *this;*/
/*
* 3. 考虑异常安全性,先用new分配新内容,再用delete释放已有内容
*/
if (this == &str)
{
return *this;
}
char *pTemp = new char[strlen(str.m_pData) + 1];
delete[]m_pData;
m_pData = NULL;
m_pData = pTemp;
strcpy(m_pData, str.m_pData);
return *this;
}
void CMyString::Print()
{
cout << m_pData << endl;
}
void Test1()
{
cout<<"测试1(把实例赋值给另一个实例)"<<endl;
char* text = "hello test1";
CMyString str1(text);
CMyString str2;
str2 = str1;
cout << "预期结果:" << text << endl;
cout << "实际结果:";
str2.Print();
cout << endl;
}
void Test2()
{
cout << "测试2(把实例赋值给自己)" << endl;
char* text = "hello test2";
CMyString str1(text);
str1 = str1;
cout << "预期结果:" << text << endl;
cout << "实际结果:";
str1.Print();
cout << endl;
}
void Test3()
{
cout << "测试3(连续赋值)" << endl;
char* text = "hello test3";
CMyString str1(text);
CMyString str2, str3;
str3 = str2 = str1;
cout << "str2预期结果:" << text << endl;
cout << "str2实际结果:";
str2.Print();
cout << endl;
cout << "str3预期结果:" << text << endl;
cout << "str3实际结果:";
str3.Print();
cout << endl;
system("pause");
}
int main(int argc, char* argv[])
{
Test1();
Test2();
Test3();
return 0;
}
其实关于内存不足的异常,感觉第二种方法是有问题的,我跑出来结果是不对的。还没有探索到原因。
3. 关于C++中的内存泄露
一般是指堆中的内存泄露。堆内存是手动malloc/realloc/new申请的,程序不会自动回收,需调用free或delete手动释放,否则会引起内存泄露【即要成对出现】。此外,还包括系统资料泄露,如socket连接使用完要释放。
申请和释放必须成对出现malloc/realloc对应free,new对应delete。前者不会运行构造/析构函数,后者会。
看被人总结了内存泄露的原因:
1. 编码错误:即堆内存malloc/realloc/new申请后,未手动释放。
2. 无主内存:申请后,指针指向内存起始地址,若丢失或修改该指针,申请的内存将丢失,且未释放。
3. 异常分支导致资源未释放
4. 隐式内存泄露:程序运行中不断申请内存,直到程序结束才释放。但因为很多程序运行时间长,来不及释放导致内存耗尽。
5. 类的析构函数为非虚函数:析构函数为虚函数,利用多态性调用指针指向对象的析构函数,而不是基类的析构函数。
详细内容在下面博客中有详细介绍:http://blog.csdn.net/kangroger/article/details/39317503