在C++中使用类中的'const'和运算符重载是否有一个很好的规则?

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正在提及).

因为我不想在这个阶段改变任何东西(这是考试测试的一部分) - 我想知道为什么会发生这种情况.

我试图删除constEducationalCentre(const EducationalCentre& obj),这确实解决了问题,但..正如我所说,我宁愿了解是什么导致这而不是删除它.

Zde*_*vic 5

使用规则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++不仅是一种面向对象的语言,因此您可以通过其他方式更改应用程序状态,也可以滥用mutableconst_cast欺骗编译器,但const在编写正确的软件和降低调试工作时使用有很多帮助.