问题:在C++中建议用const、enum、inline替换#define,为什么?
答:
1)宏的优点:
A、增强代码的复用性;
B、提高代码的性能。
2)宏的缺点:
A、不可调试;
B、不检查参数类型;
C、容易出错;
D、无法操作类的私有数据成员。
1、const修饰成员函数
在成员函数后面加const,const修饰this指针所指向的对象,也就是保证调用这个const成员函数的对象在函数内不会被改变。编译器对成员函数的处理,如图1:
图1 成员函数在编译器中的状态图
【例1】const使用在编译器中的变化
编译前:
class Date
{
private:
int _year;
int _month;
int _day;
public:
void Display() const
{
cout << "Display()const" << endl;
cout << "year:" << _year << endl;
cout << "month:" << _month << endl;
cout << "day:" << _day << endl << endl;
}
};
编译后:
class Date
{
private:
int _year;
int _month;
int _day;
public:
void Display( const Date* this)//编译后,const参数在括号内
{
cout << "Display()const" << endl;
cout << "year:" << this->_year << endl;//编译后,this指针出现
cout << "month:" << this->_month << endl;
cout << "day:" << this->_day << endl << endl;
}
};
【例2】const的使用
#define _CRT_SECURE_NO_WARNINGS 1
# include <iostream>
using namespace std;
class Date
{
private:
int _year;
int _month;
int _day;
public:
void Display()
{
cout << "Display()" << endl;
cout << "year:" << _year << endl;
cout << "month:" << _month << endl;
cout << "day:" << _day << endl << endl;
}
void Display() const
{
cout << "Display()const" << endl;
cout << "year:" << _year << endl;
cout << "month:" << _month << endl;
cout << "day:" << _day << endl << endl;
}
};
void Test()
{
Date d1;
d1.Display();
const Date d2;
d2.Display();
}
int main()
{
Test();
system("pause");
return 0;
}
思考:
1)const对象可以调用非const成员函数和const成员函数吗?
答:const对象可以调用const成员函数,不可调用非const成员函数。
2)非const对象可以调用非const成员函数和const成员函数吗?
答:非const对象不仅可以调用非const成员函数,也可调用const成员函数。
3)const对象可以调用其它的非const成员函数和const成员函数吗?
答:const对象不可以调用其他的非const成员函数,但是可以调用const成员函数。
4)非const对象可以调用其它的非const成员函数和const成员函数吗?
答:都可以调用。
【例】取地址运算符(这两个默认成员函数一般不用重新定义)
class Date
{
public:
Date* operator&()
{
return this;
}
const Date* operator&()const
{
return this;
}
private:
int _year;
int _month;
int _day;
};
2、inline(内联)
以inline修饰的函数就叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数压栈的开销,内联函数提升程序运行的效率。
(1)内联函数的特性
1)inline是一种以空间换取时间的做法,省去了调用函数额的开销,所以在代码很长/有循环/递归的函数体内不适合使用内联。
2)inline对于编译器而言只是一个建议,编译器会自动优化,如果定义为inline的函数体内有递归/循环等等,编译器优化时会自动忽略掉内联。
3)inline必须与函数定义放在一起才能成为内联函数,仅将inline放在声明前是不起作用的。
4)定义在类内的成员函数默认定义为内联函数。
5)因为构造函数和析构函数会调用基类或成员对象的构造函数和析构函数,所以不要轻易让构造函数函数和析构函数成为内联函数。
【例】
class Date
{
public:
void Func()//定义在类内部默认为内联函数
{}
void Display();//成员函数
private:
int _year;
int _month;
int _day;
};
inline void Date::Display()//成员函数定义为内联
{
cout << "year:" << _year << endl;
cout << "month:" << _month << endl;
cout << "day:" << _day << endl << endl;
}
inline void test() //全局函数定义为内联
{}
3、友元函数
友元函数用关键字friend说明。在C++中友元函数允许在类外访问该类中的任何成员,就像成员函数一样。
(1)友元函数的特性:
1)友元函数不是类的成员函数。
2)友元函数可以通过对象访问所有成员,私有和保护成员也一样。
【例】
class Date
{
public:
friend void Display(const Date& d);//友元成员函数
private:
int _year;
int _month;
int _day;
};
void Display(const Date& d)
{
cout << "year:" << d._year << endl;
cout << "month:" << d._month << endl;
cout << "day:" << d._day << endl << endl;
}
void Test()
{
Date d1;
Display(d1);
}
【例】输入输出运算符重载的友元函数
class Date
{
public:
//1、operator<<可以定义成员函数吗?
//2、返回值定义为void可以吗?
friend ostream& operator<<(ostream& os, const Date& d);
friend istream& operator>>(istream& is, Date& d);
private:
int _year;
int _month;
int _day;
};
ostream& operator<<(ostream& os, const Date& d)
{
os << "year:" << d._year << endl;
os << "month:" << d._month << endl;
os << "day:" << d._day << endl;
return os;
}
istream& operator>>(istream& is, Date& d)
{
cout << "请分别输入年月日:" << endl;
is >> d._year;
is >> d._month;
is >> d._day;
return is;
}
【例】友元类:整个类可以是另一个类的友元,那么它的成员函数和数据就可以被另一个类访问。
class Time
{
//Date是Time的友元类
friend class Date;
private:
int _hour;
int _minute;
int _second;
};
class Date
{
public:
void Display()
{
cout << "year:" << _year << endl;
cout << "month:" << _month << endl;
cout << "day:" << _day << endl;
//定义为友元类后就可以访问类Time中的所有成员
cout << "hour:" << t._hour << endl;
cout << "minute:" << t._minute << endl;
cout << "second:" << t._second << endl;
}
private:
int _year;
int _month;
int _day;
Time t;
};
void Test()
{
Date d1;
d1.Display;
}
注意:友元一定程度上破坏了C++的封装性,不宜多用,应适当使用友元。
4、类的静态成员
类里static修饰的成员,就叫做静态类成员。类的静态成员是该类型的所有对象所共享。
【例】静态成员的定义及使用
class Date
{
public:
Date()
{
cout << "Date()" << endl;
++sCount;
}
void Display()
{
cout << "year:" << _year << endl;
cout << "month:" << _month << endl;
cout << "day:" << _day << endl;
}
//静态成员函数
static void PrintCount()
{
cout << "Date count:" << sCount << endl;
}
private:
static int sCount;//静态成员变量,统计创建变量个数
int _year;
int _month;
int _day;
};
int Date::sCount = 0;//定义并初始化静态成员变量
void Test()
{
Date d1,d2,d3;//创建3个变量
//访问静态成员
Date::PrintCount();
}
int main()
{
Test();
system("pause");
return 0;
}
运行结果:
注意:静态成员没有隐含的this指针参数,所以可以使用类型+::作用域访问符直接调用静态成员函数,即静态成员属于类而不属于对象。Static成员不能定义为const。
问题:
1)静态成员函数可以访问非静态的成员吗?
答:不可以,因为没有this指针。
2)非静态的成员函数可以访问静态成员吗?
答:可以。
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/18194.html