一、
1)重载
#include <iostream>
using namespace std;
//只有参数的个数或参数类型不同,才发生函数重载
//在参数是引用类型的情况下,const、volatile的区别视为重载
//void SayHello(volatile int *age)
//{
// cout<<"hello tom"<<endl;
//}
//
//void SayHello(int *age)
//{
// cout<<"hello jerry"<<endl;
//}
//void fun(int age)
//{
// cout<<age<<endl;
//}
//
//void fun(char *pStrName)
//{
// cout<<pStrName<<endl;
//}
函数的默认参数,不构成函数重载
//void fun(int x,int y=100)
//{
//}
//
//void fun(int x,int y)
{
}
void main()
{
//fun(100);
//fun("tom");
//
//int n=100;
//const int *num=&n;
//int num=100;
//int *n=#
//SayHello(n);
每次都从内存里面去找出num
//volatile int num=100;
//int a=num;
//int b=num;
}
2)构造与析构、深拷贝与浅拷贝
在某种情况下,类中成员变量需要动态开辟内存,如果使用浅拷贝,也就是把对象里的值完全复制给另一个对象,如A=B。
这时,如果B中有一个成员变量指针已经申请了内存,那A中的那个成员变量也指向同一块内存。这就出现了问题:
当B把内存释放了,这时A的指针就是野指针。
总结: 如果一个类拥有资源,当这个类的对象发生复制过程,资源重新分配,这个过程就是深拷贝,反之,没有重新分配资源,就是浅拷贝。
#include <iostream>
#include <windows.h>
using namespace std;
//class clock
//{
// int hour,min,sec;
//public:
// void SetTime(int h,int m,int s);
// void ShowTime();
// int GetH();
//
// //内联
// //void SetTime(int h,int m,int s)
// //{
// // hour=h;
// // min=m;
// // sec=s;
// //}
//
// //void ShowTime()
// //{
// // cout<<hour<<":"<<min<<":"<<sec<<endl;
// //}
//};
//
在类的外部实现类成员方法
//void clock::SetTime(int h,int m,int s)
//{
// hour=h;
// min=m;
// sec=s;
//}
//void clock::ShowTime()
//{
// cout<<hour<<":"<<min<<":"<<sec<<endl;
//}
//构造函数:对类中的成员变量进行初始化
//
class Date
{
private:
int year;
int month;
int day;
public:
//Date d2(d1);
Date(Date &d);
Date();
void ShowDate();
void SetDate(int y,int m,int d);
void SetYear(int y);
void SetMonth(int m);
void SetDay(int d);
};
Date::Date(Date &d)
{
if (d.year<=2000)
year=d.year;
else
year=1900;
month=d.month;
day=d.day;
}
void Date::ShowDate()
{
cout<<year<<"-"<<month<<"-"<<day<<endl;
}
void Date::SetDate(int y,int m,int d)
{
year=y;
month=m;
day=d;
}
void Date::SetYear(int y)
{
year=y;
}
void Date::SetMonth(int m)
{
month=m;
}
void Date::SetDay(int d)
{
day=d;
}
Date::Date()
{
year=1900;
month=1;
day=1;
}
//析构函数:对类中的资源进行清理工作
//
class Person
{
int age;
char sex;
char *pStrName;
public:
Person(Person &p);
Person();
~Person();
void SetName(char *pStr);
void ShowName();
};
//拷贝构造函数
Person::Person(Person &p1)
{
age=p1.age;
sex=p1.sex;
//pStrName=p1.pStrName;
pStrName=new char[50]; //深拷贝
if (pStrName)
{
strcpy(pStrName, p1.pStrName);
}
}
Person::~Person()
{
if (pStrName!=NULL)//先判断再删除指针
{
delete [] pStrName;
pStrName=NULL;//删除指针之后要赋NULL,避免野指针
}
}
Person::Person()
{
age=0;
sex='m';
//pStrName="tom";
pStrName=NULL;
pStrName=new char[50];
if (pStrName!=NULL)
{
//memset(pStrName,0,50);
ZeroMemory(pStrName,50);
strcpy(pStrName,"tom");
}
}
void Person::ShowName()
{
cout<<pStrName;
}
void Person::SetName(char *pStr)
{
//pStrName=pStr;
strcpy(pStrName,pStr);
}
void main()
{
//拷贝构造函数
Date d1;
d1.SetYear(2014);
Date d2(d1);//只调用了复制构造函数
d2.ShowDate();
//{
// Person p1;
// p1.SetName("jerry");
// Person p2(p1);
// p2.ShowName();
//}
//后定义的对象,先析构
析构函数
//char name[]="jack";
//{
// Person p1;
// p1.SetName(name);
// p1.ShowName();
//}
//return;
// //构造函数
// Date d1;
// //d1.SetDate(2014,8,8);
// d1.ShowDate();
}
二、
课后习题:
1.用struc设计一个单向链表,对其添加3个成员信息,然后遍历链表打印出所有节点的内容。
#include <iostream>
#include <string.h>
using namespace std;
//用struc设计一个单向链表,对其添加3个成员信息,
//然后遍历链表打印出所有节点的内容。
struct Person
{
int code;
int age;
char strName[100];
Person *pNext;
};
int main()
{
Person p1,p2,p3,*pHead;
p1.code=10001;
p1.age=100;
strcpy(p1.strName,"jack");
p2.code=10002;
p2.age=200;
strcpy(p2.strName,"tom");
p3.code=10003;
p3.age=300;
strcpy(p3.strName,"jerry");
pHead=&p1;
//pHead->pNext=&p2;
p1.pNext=&p2;
p2.pNext=&p3;
p3.pNext=NULL;
Person *pPos=pHead;
while(pPos!=NULL)
{
cout<<"code:"<<pPos->code<<endl;
cout<<"age:"<<pPos->age<<endl;
cout<<"name:"<<pPos->strName<<endl;
pPos=pPos->pNext;
}
return 0;
}
2.Person构造,析构、深拷贝 实现以下
3.用class设计一个Person单向链表
#include <iostream>
using namespace std;
//位运算求某数的绝对值
int MyAbs(int num)
{
int a=num>>31;//得到符号位
int tmp=a^num;
tmp=tmp-a;
return tmp;
}
//用struc设计一个单向链表,对其添加3个成员信息,
//然后遍历链表打印出所有节点的内容。
struct Person
{
int code;
int age;
char strName[100];
Person *pNext;
};
void main()
{
//int n=-100;
//int result=MyAbs(n);
//cout<<result<<endl;
Person p1,p2,p3,*pHead;
p1.code=10001;
p1.age=100;
//类型不相同时需要使用strcpy,将"jack" 拷贝到指定内存中
strcpy(p1.strName,"jack");
p2.code=10002;
p2.age=200;
strcpy(p2.strName,"tom");
p3.code=10003;
p3.age=300;
strcpy(p3.strName,"jerry");
pHead=&p1;
//pHead->pNext=&p2;
p1.pNext=&p2;
p2.pNext=&p3;
p3.pNext=NULL;
Person *pPos=pHead;
while(pPos!=NULL)
{
cout<<"code:"<<pPos->code<<endl;
cout<<"age:"<<pPos->age<<endl;
cout<<"name:"<<pPos->strName<<endl;
pPos=pPos->pNext;
}
}
要求:
可以遍历此链表
可以动态添加链表的子节点
每个节点之间可以相互拷贝(拷贝构造函数、深拷贝的实现)
释放节点的时候不能有内存泄漏
4.设计一个手机类,并实现相关功能函数(不少于5个)
要求:在拷贝构造函数中实现深拷贝
加深理解构造函数与析构函数