C++ 在C++;,具有常量数据成员的类是否可以没有复制赋值运算符?

C++ 在C++;,具有常量数据成员的类是否可以没有复制赋值运算符?,c++,copy-assignment,C++,Copy Assignment,我正在设计一个类,它应该有一个名为K的常量数据成员。我还希望这个类有一个copy赋值操作符,但是编译器似乎会从任何具有const数据成员的类中隐式删除copy赋值操作符。此代码说明了基本问题: class A { private: const int K; public: A(int k) : K(k) {} // constructor A() = delete; // delete default constructor, since

我正在设计一个类,它应该有一个名为
K
的常量数据成员。我还希望这个类有一个copy赋值操作符,但是编译器似乎会从任何具有const数据成员的类中隐式删除copy赋值操作符。此代码说明了基本问题:

class A
{
    private:
       const int K;
    public:
       A(int k) : K(k) {} // constructor
       A() = delete; // delete default constructor, since we have to set K at initialization

       A & operator=(A const & in) { K = in.K; } // copy assignment operator that generates the error below
}
下面是它产生的错误:

constructor.cpp:13:35: error: cannot assign to non-static data member 'K' with const- 
qualified type 'const int'
            A & operator=(A const & in) { K = in.K; }
                                          ~ ^
constructor.cpp:6:13: note: non-static data member 'K' declared const here
            const int K;
            ~~~~~~~~~~^
1 error generated.
我想我理解编译器为什么这样做;我想复制到的类的实例必须先存在,然后才能被复制到,并且我不能在目标实例中分配到
K
,如果它是常量,就像我在上面尝试做的那样


我对这个问题的理解正确吗?如果是这样,有没有办法解决这个问题?也就是说,我可以为我的类定义一个复制构造函数,仍然给出<代码> k< /Cord> const类的保护吗?< /p>

<强> C++中,一个具有<代码> const < />代码的类。数据成员可能有一个复制构造函数。< /强>

#include <iostream>

class A
{
private:
    const int k_;
public:
    A(int k) : k_(k) {}
    A() = delete;
    A(const A& other) : k_(other.k_) {}

    int get_k() const { return k_; }
};

int main(int argc, char** argv)
{
    A a1(5);
    A a2(a1);

    std::cout << "a1.k_ = " << a1.get_k() << "\n";
    std::cout << "a2.k_ = " << a2.get_k() << "\n";
}
class A
{
private:
    const int k_;
public:
    A(int k) : k_(k) {}
    A() = delete;
    A(const A& other) : k_(other.k_) {}

    int get_k() const { return k_; }
};

int main(int argc, char** argv)
{
    A a1(5);
    A a2(0);

    a2 = a1;
}
class A
{
private:
    const int k_;
public:
    A(int k) : k_(k) {}
    A() = delete;
    A(const A& other) : k_(other.k_) {}

    A& operator=(A const& other)
    {
        // do nothing
        return *this;
    }

    int get_k() const { return k_; }
};

int main(int argc, char** argv)
{
    A a1(5);
    A a2(0);

    a2 = a1;
}


< > >强> C++中,一个类具有“代码> const < /COD>”数据成员可能不使用默认赋值操作符。< /强>

#include <iostream>

class A
{
private:
    const int k_;
public:
    A(int k) : k_(k) {}
    A() = delete;
    A(const A& other) : k_(other.k_) {}

    int get_k() const { return k_; }
};

int main(int argc, char** argv)
{
    A a1(5);
    A a2(a1);

    std::cout << "a1.k_ = " << a1.get_k() << "\n";
    std::cout << "a2.k_ = " << a2.get_k() << "\n";
}
class A
{
private:
    const int k_;
public:
    A(int k) : k_(k) {}
    A() = delete;
    A(const A& other) : k_(other.k_) {}

    int get_k() const { return k_; }
};

int main(int argc, char** argv)
{
    A a1(5);
    A a2(0);

    a2 = a1;
}
class A
{
private:
    const int k_;
public:
    A(int k) : k_(k) {}
    A() = delete;
    A(const A& other) : k_(other.k_) {}

    A& operator=(A const& other)
    {
        // do nothing
        return *this;
    }

    int get_k() const { return k_; }
};

int main(int argc, char** argv)
{
    A a1(5);
    A a2(0);

    a2 = a1;
}
产生编译时错误:

const_copy_constructor.cpp: In function ‘int main(int, char**)’:
const_copy_constructor.cpp:18:10: error: use of deleted function ‘A& A::operator=(const A&)’
   18 |     a2 = a1;
      |          ^~
const_copy_constructor.cpp:1:7: note: ‘A& A::operator=(const A&)’ is implicitly deleted because the default definition would be ill-formed:
    1 | class A
      |       ^
const_copy_constructor.cpp:1:7: error: non-static const member ‘const int A::k_’, can’t use default assignment operator


< C++ >一个类,具有<代码> const 数据成员可以使用非默认赋值操作符,只要你不试图改变<代码> const 数据成员,但如果不能修改一个基本成员,最好仔细考虑使用这个赋值操作符的意义。< /强>

#include <iostream>

class A
{
private:
    const int k_;
public:
    A(int k) : k_(k) {}
    A() = delete;
    A(const A& other) : k_(other.k_) {}

    int get_k() const { return k_; }
};

int main(int argc, char** argv)
{
    A a1(5);
    A a2(a1);

    std::cout << "a1.k_ = " << a1.get_k() << "\n";
    std::cout << "a2.k_ = " << a2.get_k() << "\n";
}
class A
{
private:
    const int k_;
public:
    A(int k) : k_(k) {}
    A() = delete;
    A(const A& other) : k_(other.k_) {}

    int get_k() const { return k_; }
};

int main(int argc, char** argv)
{
    A a1(5);
    A a2(0);

    a2 = a1;
}
class A
{
private:
    const int k_;
public:
    A(int k) : k_(k) {}
    A() = delete;
    A(const A& other) : k_(other.k_) {}

    A& operator=(A const& other)
    {
        // do nothing
        return *this;
    }

    int get_k() const { return k_; }
};

int main(int argc, char** argv)
{
    A a1(5);
    A a2(0);

    a2 = a1;
}

不产生编译时错误。

对于
来说,拥有
常量
数据成员通常是错误的。通常最好是通过使其
私有化而不提供setter来保证其恒定性。它比
const
弱,但取舍通常倾向于不在这里使用
const
。“我可以为我的类定义一个复制构造函数吗?”复制构造函数很容易实现,但赋值操作符却不容易实现。由您决定在不改变
k
的情况下分配给
a
意味着什么。您可能会发现它没有意义,这意味着尝试实现操作符没有意义。如果您仔细想想,一个对象被构造,它的常量变量在创建时第一次初始化,这一切都很好。现在是将其分配给另一个对象的时候了,此时您不能将常量成员数据重新分配给另一个值,并且违反了常量的定义。“K”应该是
const
或不是
const
。没有中间立场。如果需要修改它,则不应将其标记为
const