const成员函数
- const修饰成员函数的时候,const需要放在成员函数的后面,不能放在一开始,如果放在一开始的话,那么const其实是在修饰成员函数的返回值,而不是在修饰成员函数了
- const成员函数中不能修改成员变量
- 普通成员函数中可以修改成员变量
- 到底要不要使用const去修饰成员函数,就看你的函数中的变量需不需要被修改,如果希望其被修改的话,还是不要给成const,因为给成const的话,就不能去修改他了
const修饰类的成员函数
- 将const修饰的类成员函数称之为const成员函数,const修饰类成员函数,实际修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改
看下面的代码
class Date
{
public:
Date(int year = 1900, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
cout << "Date(int,int,int):" << this << endl;
}
Date(const Date& d)
{
_year = d._year;
_month = d._month;
_day = d._day;
cout << "Date(Date&):" << this << endl;
}
Date& operator=(const Date& d)
{
if (this != &d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
return *this;
}
void TestFunc1()
{
this->_day++;
}
void TestFunc2()const
{
this->_day++;
}
void TestFuncWithConst()const
{
}
void TestFuncWithoutConst()
{
TestFunc2();
}
~Date()
{
cout << "~Date():" << this << endl;
}
Date* operator&()
{
return this;
}
const Date* operator&()const
{
return this;
}
private:
int _year;
int _month;
mutable int _day;
};
int main()
{
Date d1(2019, 3, 24);
const Date d2(2019, 3, 25);
cout << &d2 << endl;
d1.TestFunc1();
d1.TestFunc2();
return 0;
}
- 但是有些时候,我还是希望有些值是可以变化的,加上const之后修改成员函数,那么成员函数里面所有的值都不能发生变化了,如果我希望有些值仍然是可以修改的话,那么我可以再某些变量的前面加上mutable,加上mutable之后就表明这个变量可以在const所修饰的成员变量中被修改
请思考下面的几个问题
这两个默认成员函数一般不用重新定义 ,编译器默认会生成。
- const对象可以调用非const成员函数吗?
- 不可以,原因在于用const所修饰的变量本质上是一个常量,所以也就是说常量中的内容是不可以被修改的,但是普通的成员函数,在函数中可以修改当前对象的成员,所以两者是互相矛盾的,所以无法调用
- 非const对象可以调用const成员函数吗?
- 答案是可以的,因为普通类型的对象既可以修改成员变量的值,也可以不去修改成员变量的值,那到底要不要修改,根据情况而定就可以了。
- const成员函数内可以调用其它的非const成员函数吗?
- 是不可以的,因为如果你把一个函数声明为const类型的函数,那么就说明这个函数是只读的,是不可以修改的,而非const的成员函数是可读可写的
- 非const成员函数内可以调用其它的const成员函数吗?
- 可以,因为外层函数的类型是 Date* const:可读可写,而内层函数的类型是const Date* const: 只读,外层可以修改也可以不修改,到底要不要修改,根据具体情况而定就可以了
取地址及const取地址操作符重载
const Date* operator&()const
{
return this;
}
int main()
{
Date d1(2019, 3, 24);
const Date d2(2019, 3, 25);
cout << &d2 << endl;
d1.TestFunc1();
d1.TestFunc2();
return 0;
}
class Date
{
public :
Date* operator&()
{
return this ;
}
const Date* operator&()const
{
return this ;
}
private :
int _year ;
int _month ;
int _day ;
};
- 这两个运算符一般不需要重载,使用编译器生成的默认取地址的重载即可,只有特殊情况,才需要重载,比如想让别人获取到指定的内容
程序的运行结果是什么
class Date
{
public:
Date(int year = 1900, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
cout << "Date(int,int,int):" << this << endl;
}
Date(const Date& d)
{
_year = d._year;
_month = d._month;
_day = d._day;
cout << "Date(Date&):" << this << endl;
}
Date& operator=(const Date& d)
{
cout << this << "=" << &d << endl;
if (this != &d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
return *this;
}
~Date()
{
cout << "~Date():" << this << endl;
}
int _year;
int _month;
int _day;
};
Date TestDate(Date& d)
{
Date temp(d);
temp._day += 1;
return d;
}
void TestDate()
{
Date d1(2019, 3, 24);
Date d2(d1);
d1 = TestDate(d2);
}
int main()
{
TestDate();
return 0;
}
- 打印结果如下所示:
class Date
{
public:
Date(int year = 1900, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
cout << "Date(int,int,int):" << this << endl;
}
Date(const Date& d)
{
_year = d._year;
_month = d._month;
_day = d._day;
cout << "Date(Date&):" << this << endl;
}
Date& operator=(const Date& d)
{
cout << this << "=" << &d << endl;
if (this != &d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
return *this;
}
~Date()
{
cout << "~Date():" << this << endl;
}
int _year;
int _month;
int _day;
};
Date& TestDate(Date& d)
{
Date temp(d);
temp._day += 1;
return d;
}
void TestDate()
{
Date d1(2019, 3, 24);
Date d2(d1);
d1 = TestDate(d2);
}
int main()
{
TestDate();
return 0;
}
- 结果如下所示:
const 重载
- 上面的两个函数是可以形成重载的,之所以可以形成重载是因为有const进行修饰,因为一旦加了const进行修饰的话,两个函数的this指针的类型就不一样了,这也就是为什么两个函数可以形成重载的原因