C++ ';类型非静态常量成员can';t使用默认赋值运算符';-这是什么意思?

C++ ';类型非静态常量成员can';t使用默认赋值运算符';-这是什么意思?,c++,constants,C++,Constants,此类正在标记以下错误: '非静态常量成员'const int member::membershipNo',无法使用默认赋值运算符'。奇怪的是,这段代码在另一个项目中被重复,并且工作得非常完美。你能帮我把它修好吗 成员:h class Member : public Person { public: Member(); Member(int membershipNo); virtual ~Member(); int

此类正在标记以下错误: '非静态常量成员'const int member::membershipNo',无法使用默认赋值运算符'。奇怪的是,这段代码在另一个项目中被重复,并且工作得非常完美。你能帮我把它修好吗

成员:h

class Member : public Person
    {
    public:
        Member();
        Member(int membershipNo);
        virtual ~Member();

        int getMembershipNo() const;

    private:
        const int membershipNo;

        friend class boost::serialization::access;
        template<class Archive>
        void serialize(Archive& ar, const unsigned int version)
        {
            ar & boost::serialization::base_object<Person>(*this);
            ar & membershipNo;
        }

    };

发生的情况是,某些客户端代码正试图使用将一个
成员
实例分配给另一个实例。因为您有一个常量数据成员,所以这无法工作。只有当某些代码试图进行赋值时,才会出现错误,这就是为什么在另一个项目中,同一个类似乎可以“工作”的原因


就纠正方法而言,选项是A)不执行赋值,或B)使数据成员非常量。

大概是在代码中的某个地方,您将赋值给一个
成员,如下所示:

Member m1, m2;
m1 = m2;
或者在要求类型可赋值的上下文中使用它

由于您没有为
成员
提供自己的赋值运算符重载,因此隐式定义的默认赋值运算符通常会生效。但是,由于您有一个
const
数据成员,编译器不会隐式地为您定义一个。你需要自己提供

这是有意义的,因为,想象一下,在我刚才给出的代码示例中,编译器应该如何处理
m1
membershipNo
成员?是否应该为其分配
m2
membershipNo
?如果
membershipNo
const
,它如何做到这一点?在这种情况下,编译器只会说“不,我做不到。”

如果
X
类的默认复制/移动分配运算符具有以下内容,则该运算符被定义为已删除:

  • const
    非类类型(或其数组)的非静态数据成员
  • [……]
正如我所说的,为了能够与
成员
进行作业,您需要提供自己的作业操作员:

Member& Member::operator=(const Member& other)
{
  // Copy things from other to this
}
然而,这里存在着拥有
const
成员的问题。如果您按照说明提供了自己的复制分配运算符,并且您没有复制到
成员身份no
,那么您真的复制了另一个对象了吗?从逻辑上讲,具有任何
const
状态的对象不应该被分配到

但是,使用复制构造函数是完全可以的-您只需确保在成员初始化列表中初始化
membershipNo

Member::Member(const Member& other)
  : membershipNo(other.membershipNo)
{
  // ...
}
然后你可以做:

Member m1;
Member m2 = m1;

啊,是的,你是对的。非常感谢。那么,是否无法复制/分配具有常量成员的实例?为什么复制会违反更改常量数据值的规则?@Frammo copying可以。分配不是。分配LHS=RHS时,LHS已初始化,分配意味着其状态发生变化。如果州是常数…啊,是的,谢谢。那么,没有办法使用复制构造函数复制具有常量数据的对象吗?@Frammo copy-constructor很好。除非您提供自己的副本,否则副本分配不可用。对不起。与复制构造函数和赋值运算符重载方法混淆。我给了你一个被接受的答案,因为它比第一个答案稍微深入一点。
Member m1;
Member m2 = m1;