dev*_*r10 1 c++ const copy-constructor
我有一段这样的代码:
class EducationalCentre
{
string _centreName;
vector<Course> _courses; // courses offered by the Centre
Collection<Course*, Student*, 150> _applicants;
public:
EducationalCentre(string name="<name>")
{
_centreName = name;
}
EducationalCentre(const EducationalCentre& obj)
:_courses(obj._courses), _applicants(obj._applicants)
{
_centreName = obj._centreName;
}
};
Run Code Online (Sandbox Code Playgroud)
现在,在这部分_applicants(obj._applicants)复制构造标题中,周围有一条波浪形的红线(obj,将其悬停在错误上,说明类型不兼容(const正在提及).
因为我不想在这个阶段改变任何东西(这是考试测试的一部分) - 我想知道为什么会发生这种情况.
我试图删除const从EducationalCentre(const EducationalCentre& obj),这确实解决了问题,但..正如我所说,我宁愿了解是什么导致这而不是删除它.
使用规则const是每当你可以使用它:)
当然,与所有最佳实践一样,也存在异常,但一般情况下,const如果不改变对象的状态,则应始终努力制作非静态方法.
您遇到问题的原因是Collection复制构造函数对其用作源对象的实例采用非const引用.
复制构造函数可以将const或非const引用作为其参数,但IMO,非const只应在没有选择时使用,这很少.基于另一个对象创建对象不应该更改源对象,因此应将其标记为const.
正如我在评论中指出的那样,通用类与使用const引用的copy ctor无关.实际上,如果你看一下,std::vector你会看到它有一个复制构造函数,它接受一个const引用.你在Collection参数的复制构造函数中使用的一些方法可能是非const的,这就是为什么你不能使参数const.解决方案是使违规方法也成为常量.
这带来了一个重要的观点:constness是病毒式的.如果标记方法const,则它自己调用的所有其他方法也必须是const.对于const对象的调用方法也是如此 - 您只能调用const方法.如果你从一开始就不这样做,你可能会遇到这样一种情况:制作一个方法const导致改变其他方法的整个链,因此更容易放弃.
为什么constness是好的:大多数错误是由于以意想不到的方式改变应用程序状态引起的 - 只要问一下那些对不可变性赞不绝口的函数式编程粉丝:).const方法不能改变对象的状态,因此它消除了意外更改的可能性:例如,如果在const方法的中间抛出异常,则可以确保该对象不在某些半修改中使类不变量无效的状态.
现在,C++不仅是一种面向对象的语言,因此您可以通过其他方式更改应用程序状态,也可以滥用mutable和const_cast欺骗编译器,但const在编写正确的软件和降低调试工作时使用有很多帮助.