我们来一道c++笔试题:
统计对象中某个成员变量的访问次数。
分析一下,这道题想让我们做什么?
实现一个统计功能,统计对象里面的某个成员变量被访问了多少次(包括读的次数和写的次数)
那我们来实现一下该功能吧。
#include<iostream>
using namespace std;
class Object
{
private:
int m_value;
int m_count; //用来统计访问次数
public:
Object(int value = 0):m_value(value),m_count(0) {}
int get_value()
{
m_count++;
return m_value;
}
void set_value(int value)
{
m_count++;
m_value = value;
}
//获取访问次数
int get_count()
{
return m_count;
}
};
int main()
{
Object obj;
//这里访问了三次value
cout<< "value:" << obj.get_value()<<endl;
obj.set_value(30);
cout<< "value:" << obj.get_value()<<endl;
cout<< "count:" << obj.get_count()<<endl;
return 0;
}
程序运行结果
好像题目的功能实现了呢,交卷!
(坏笑)可是当你交卷后,面试官却只给了你 50 分,难道不对?
其实基本上对了,但是有些情况我们要考虑。比如
#include<iostream>
using namespace std;
class Object
{
private:
int m_value;
int m_count; //用来统计访问次数
public:
Object(int value = 0):m_value(value),m_count(0) {}
int get_value()
{
m_count++;
return m_value;
}
void set_value(int value)
{
m_count++;
m_value = value;
}
//获取访问次数
int get_count()
{
return m_count;
}
};
int main()
{
Object obj;
//这里访问了三次value
cout<< "value:" << obj.get_value()<<endl;
obj.set_value(30);
cout<< "value:" << obj.get_value()<<endl;
cout<< "count:" << obj.get_count()<<endl<<endl;
/***** 新添加的代码1 start *****/
//我们有时候需要定义一个只读对象
const Object obj1(688);
cout<< "value:" << obj1.get_value()<<endl;
obj1.set_value(300);
/***** 新添加的代码1 end *****/
return 0;
}
编译一下,报错了。
意料之中的事情呢。我们知道,只读对象只能调用 const 成员函数。那我们先改成 const 成员函数吧。
编译一下,又报错了。
图中可以看到,我们试图在 const 成员函数中修改成员变量,怪不得编译器要报错。那我们现在就遇到难题了。
有什么办法可以解决这个问题吗???其实是有的。看一看吧
#include<iostream>
using namespace std;
class Object
{
private:
mutable int m_value;
mutable int m_count; //用来统计访问次数
public:
Object(int value = 0):m_value(value),m_count(0) {}
int get_value() const
{
m_count++;
return m_value;
}
void set_value(int value) const
{
m_count++;
m_value = value;
}
//获取访问次数
int get_count() const
{
return m_count;
}
};
int main()
{
Object obj;
//这里访问了三次value
cout<< "value:" << obj.get_value()<<endl;
obj.set_value(30);
cout<< "value:" << obj.get_value()<<endl;
cout<< "count:" << obj.get_count()<<endl<<endl;
/***** 新添加的代码1 start *****/
//我们有时候需要定义一个只读对象
const Object obj1(688);
cout<< "value:" << obj1.get_value()<<endl;
obj1.set_value(300);
cout<< "count:" << obj1.get_count()<<endl<<endl;
/***** 新添加的代码1 end *****/
return 0;
}
C++中有这么一个关键字 mutable
- mutable 成员变量将永远处于可修改的状态
- mutable 是为了突破 const 函数的限制而设计的
- mutable 在实际开发中被严禁滥用
大家会不会觉得很奇怪,mutable 这个家伙的出现,使得 const 名存实亡。
- mutable 成员变量破坏了只读对象的内部状态
- const 成员函数保证只读对象的状态不变性
- mutable 成员变量的出现无法保证状态不变性
所以实际开发 mutable 用的非常非常少。
如果刚才的代码提交给面试官能得满分了吗?
可能不行哦,毕竟你用了被大家讨厌的 mutable。
那我们该怎么做???
#include<iostream>
using namespace std;
class Object
{
private:
int* const m_value;
int* const m_count; //用来统计访问次数
public:
Object(int value = 0):m_value(new int(value)),m_count(new int(0)) {}
~Object()
{
delete m_value;
delete m_count;
}
int get_value() const
{
//在这里,我们并没有改变指针的地址
(*m_count)++;
return *m_value;
}
void set_value(int value) const
{
(*m_count)++;
*m_value = value;
}
//获取访问次数
int get_count() const
{
return *m_count;
}
};
int main()
{
Object obj;
//这里访问了三次value
cout<< "value:" << obj.get_value()<<endl;
obj.set_value(30);
cout<< "value:" << obj.get_value()<<endl;
cout<< "count:" << obj.get_count()<<endl<<endl;
/***** 新添加的代码1 start *****/
//我们有时候需要定义一个只读对象
const Object obj1(688);
cout<< "value:" << obj1.get_value()<<endl;
obj1.set_value(300);
cout<< "count:" << obj1.get_count()<<endl<<endl;
/***** 新添加的代码1 end *****/
return 0;
}
这样子的代码提交给面试官他肯定会很高兴的。