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
。