1.const成员函数
写法: void print () const{}
const修饰this指针所指向的对象不会被改变
<1>若将成员成员函数声明为const,则该函数不允许修改类的数据成员
例:
class a{
public:
int func(int a) const
{
d1 = a; //会显示表达式必须是可修改的左值
}
private:
int d1;
};
<2>const成员函数可以被具有相同参数列表的非const成员函数重载
例:
class b{
public:
int func(int a, int b)
{
return a + b;
}
int func(int a, int b) const
{
return a * b;
}
private:
int d;
};
int main()
{
const b l1;
b l2;
cout << l1.func(3, 4) << endl; //调用int func(int a, int b) const函数
cout << l2.func(3, 4) << endl; //调用int func(int a, int b)函数
system("pause");
return 0;
}
总结:
const成员函数可以访问非const对象、const对象、非const对象数据成员,const对象数据成员
非const成员函数可以访问非const对象、const对象、非const数据成员,但不能访问const对象的数据成员
2.内联函数
用inline修饰的函数叫内联函数,编译时编译器会将内联函数展开,没有栈帧开销,用于提升程序运行效率
内联的特性:
1、inline是一种空间换时间的做法
2、inline对于编译器而言是一种建议,编译器会自动优化,如果定义inline函数体内有循环/递归,编译器优化时会忽略
3、inline必须在函数定义时放在一起
4、定义在类内的成员函数默认定义为内联函数
3.友元
C++中类受保护成员变量,在类外时无法访问的,有时候我们就需要访问类内受保护的成员变量,这时就需要在成员前加关键字friend说明
友元的特性:
<1>友元函数不是类的成员函数
<2>友元函数可以通过对象访问所有成员,私有和保护成员也一样
<3>但友元一定程度上破坏了C++的封装,所以在恰当的地方使用友元
class Date{
void print(const Date& d);
friend void show(const Date& d);
private:
int _year;
int _month;
int _day;
};
void print(const Date& d)
{
cout << d._year << endl; //_year是私有变量,类外不能访问,所以出错
}
void show(const Date& d)
{
cout << d._year << endl; //show函数经过friend修饰,成为友元函数,所以该函数在类外调用时可以访问私有变量
}
整个类都可以时另一个类的友元,另一个类可以访问该类的所有成员
例
class birthday{
friend class student;
private:
int _year;
int _month;
int _day;
};
class student{
void show(){
cout << _name << "-" << _sex << "-" << _age << "-" ;
cout << _b._year << "-" << _b._month << "-" << _b._day << endl;
}
private:
int _age;
char* _sex;
char* _name;
birthday _b;
};
4.N中构造拷贝构造的优化
Test1中调用了___次AA的拷贝构造函数, ___次AA的赋值运算符函数的重载。
Test2中调用了___次AA的拷贝构造函数, ___次AA的赋值运算符函数的重载。
Test3中调用了___次AA的拷贝构造函数, ___次AA的赋值运算符函数的重载。
#include <iostream>
#include <assert.h>
#include <Windows.h>
using namespace std;
class AA
{
public:
AA(){
cout << "AA()" << endl;
}
~AA(){
cout << "~AA()" << endl;
}
AA(const AA& d){
cout << "AA(const AA& d)" << endl;
}
AA& operator=(const AA& d){
cout << "AA& operator=(const AA& d)" << endl;
return *this;
}
};
AA f(AA a)
{
return a;
}
void Test1()
{
AA a1;
a1 = f(a1);
}
void Test2()
{
AA a1;
AA a2 = f(a1);
}
void Test3()
{
AA a1;
AA a2 = f(f(a1));
}
int main()
{
Test1();
system("pause");
return 0;
}
Test1():
Test2()
Test3():
所以结果为:
Test1中调用了2次AA的拷贝构造函数, 1次AA的赋值运算符函数的重载。
Test2中调用了2次AA的拷贝构造函数, 0次AA的赋值运算符函数的重载。
Test3中调用了3次AA的拷贝构造函数, 0次AA的赋值运算符函数的重载。