我们需要的是更高端大气上档次的代码 :)
头文件的防卫式声明
#Date.h
#ifndef __DATE__
#define __DATE__
#endif
这样书写的主要目的就是保证头文件只能被include一次,当工程过大的时候,可以防止多次include同一个头文件情况的发生。
头文件加载的符号区别
#include "Date.h"
#include <cstdio>
通过“ ”和<>这两种方式都可以完成include这一操作,但是这两者之间存在着区别。#include“ ”是从当前目录下开始搜索,然后再是系统目录和PATH环境目录(编译器设置)所列的目录,而<>则直接从系统目录下开始搜索然后搜索PATH环境目录,并不会搜索当前的目录,这是这两种头文件加载方式的不同
头文件的布局
#ifndef __DATE__
#define __DATE__
前置声明
用于声明该类中需要使用的头文件和类以及函数。
#include <iostream>
class Date;
Date& __doassign(Date* ths, const Date& other);
类-声明主体
class Date
{
public:
//构造器
Date(int y = 2000, int m = 1 ,int d=1)
:year(y) ,month(m) ,day(d)
{ }
/*~Date();析造函数*/
//获取年月日函数
int getyear() const { return year; }
int getmonth() const { return month; }
int getday() const { return day; }
//操作符函数
Date& operator = (const Date&);
//内置打印函数
void print();
private://private数据
int year;
int month;
int day;
//友元函数,用于操作符运算
friend Date& __doassign(Date*, const Date&);
};
类-函数定义
//'='操作符运算
inline Date&
__doassign(Date* ths,const Date& other)
{
ths->year=other.year;
ths->month=other.month;
ths->day=other.day;
ths->indata=other.indata;
return *ths;
}
inline Date&
Date::operator = (const Date& other)
{
return __doassign(this,other);
}
//内置打印函数
inline void
Date::print()
{
std::cout<<year<<'-'<<month<<'-'<<day<<'\n';
}
以上就是一个头文件创建类的主要内容。
构造器
在独特的C++语言环境下,C++提供给我们一种特有的构造器方法
//构造器
Date(int y = 2000, int m = 1 ,int d=1)
:year(y) ,month(m) ,day(d)
{ }
在之前的C语言中我们使用以下方法完成构造
Date(int y,int m,int d)
{
this.year=y;
this.month=m;
this.day=d;
}
这两种方法在C++环境下都可以完成对类的初始化进程,但是推荐使用C++默认的构造器方法,这种方法不但简化初始化赋值的过程,同时也保留了{ }内赋值的方法;也就是说我们可以在初始化对year,month,day进行赋值之后也可以使用函数在{ }中使用直接进行操作;而且相较于之前的赋值方法,C++提供的赋值方法在页面上显得更加简洁。无论是否需要在{ }内进行操作,C++提供的方法都相较于之前的效率更高。
函数重载
以构造器为例子:
//构造器
Date(int y, int m ,int d)
:year(y) ,month(m) ,day(d)
{}
Date(int y, int m)
:year(y) ,month(m) ,day(0)
{}
Date()
:year(0), month(0) ,day(0)
{}
就构造器而言,只需要逻辑上不存在缺陷,以下构造器代码就可以完成绝大部分功能:
public:
//构造器
Date(int y = 2000, int m = 1 ,int d=1)
:year(y) ,month(m) ,day(d)
{}
const位置标识
在函数设计中还需要注意const位置不同所带来的问题
//获取年月日
int getyear() const { return year; }
int getmonth() const { return month; }
int getday() const { return day; }
这样书写的主要原因在于,存在用户可能使用以下方式进行使用:
{
const Date a(2000,1,1);
cout<<a.getyear();
}
使用const强调a的值无法改变,假如我们在之前获取年月日的函数后不加入const,那样就会造成变量a无法正常使用getyear()函数,这就是我们在设计该函数的一个失败。
对于一些函数在处理过程中不会改变该类数据的,或者说是仅用于显示和直接返回数据值的,需要考虑使用const,满足使用的需求。
参数传递
一般而言,参数传递可以分为传值和传递引用或者指针(引用和指针底层一致,下文一致使用引用)。
public:
//构造器
Date(int y = 2000, int m = 1 ,int d=1)
:year(y) ,month(m) ,day(d)
{}
//操作符
Date& operator = (const Date&);
//友元函数,用于操作符运算
friend Date& __doassign(Date*, const Date&);
在以上例子中我们可以看到函数中在传引用时,还有const常量符号,这就表示这个值并不能改变,这个写法不但对于使用者,同时对设计者自身来说也是极其有益的。对于使用者来说,满足了使用者的需求(在变量前加const传入);对于设计者来说这也是提示自己这个变量仅用于使用,无法改变。
friend友元函数
//友元函数,用于操作符运算
friend Date& __doassign(Date*, const Date&);
操作符重载
不同与在C语言中,只能使用函数进行操作,C++里操作符也是一种函数。
//操作符重载-1
//'>'操作符运算
inline bool
__doagt(Date* ths,const Date& other)
{
if(ths->indata>other.indata)
return true;
return false;
}
inline bool
Date::operator > (const Date& other)
{
return __doagt(this,other);
}
{
Date a,b;
cout<<(a>b);
}
在使用操作符进行重载时,操作符运算一般是左数进行运算,如果左数存在对操作符的重载,则进行操作符的重载操作。在>函数中this指针特指进行操作符>运算的左数,即例中a调用>方法,传参(this即a自身,b)。
inline Date&
__pluse(Date* ths,const Date& other)
{ ths->data=other.data;
return *ths;
}//以上是操作符运算本体
//操作符重载
inline Date&
Date::operator += (const Date& other)
{
return __pluse(this,other);
}
inline void
Date::operator += (const Date& other)
{
return __pluse(this,other);
}