使用赋值运算符 =? 时 C++ 中的编译错误
Posted
技术标签:
【中文标题】使用赋值运算符 =? 时 C++ 中的编译错误【英文标题】:Compilation error in C++ when using an assignment operator =? 【发布时间】:2018-11-08 04:42:24 【问题描述】:我编写了一个作为家庭作业交给我的程序(它有点长)。问题是它在 CodeBlocks
中编译,但在 Visual Studio 2017 中没有编译它说 - binary '=': no operator found which takes a right-hand operand of type 'CAutomobile' (or there is no acceptable conversion
。
我想问为什么是因为我自己找不到错误?我尝试评论运营商=
function,但错误仍然存在。
#include <iostream>
#include <algorithm>
#include <string>
#include <stdlib.h>
using namespace std;
class CVehicle
string name;
int year;
public:
CVehicle()
name = "Car";
year = 1990;
CVehicle(string n, int y)
name = n;
year = y;
CVehicle(const CVehicle& vc)
name = vc.name;
year = vc.year;
void setName(string n)
name = n;
void setYear(int y)
year = y;
string getName()
return name;
int& getYear()
return year;
virtual void Print(ostream& os) = 0;
;
class CAutomobile :public CVehicle
double litres;
public:
CAutomobile() :CVehicle()
litres = 7.2;
CAutomobile(string nm, int yr, double l) :CVehicle(nm, yr)
litres = l;
void setLitres(double l)
l = litres;
double& getLitres()
return litres;
void Print(ostream& os) override
os << getName() << endl;
os << getYear() << endl;
os << litres << endl;
friend bool operator< (CAutomobile a1, CAutomobile a2)
if (a1.litres < a2.litres)
return true;
return false;
CAutomobile operator= (CAutomobile& at)
CAutomobile au;
au.getName() = at.getName();
au.getYear() = at.getYear();
au.getLitres() = at.getLitres();
return au;
CAutomobile operator+(CAutomobile aut)
CAutomobile a;
a.getLitres() = getLitres() + aut.getLitres();
return a;
friend ostream& operator<< (ostream& o, CAutomobile a)
o << a.getName() << endl;
o << a.getYear() << endl;
o << a.getLitres() << endl;
return o;
;
int main()
CAutomobile a[] =
CAutomobile(),
CAutomobile("Wolkswagen",1970,80.5),
CAutomobile("Fiat",1979,21.9),
CAutomobile("Opel",1978,13.7)
;
for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++)
cout << "Name" << ' ' << a[i].getName() << endl;
cout << "Year" << ' ' << a[i].getYear() << endl;
cout << "Litres" << ' ' << a[i].getLitres() << endl;
int range = 2016 - 1990 + 1;
for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++)
a[i].setLitres(rand() % 100 + 1);
a[i].setYear(rand() % range + 1996);
//сортираме масива по литри и извеждаме
//най малкия (първия) му елемент
for (int i = 0; i < sizeof(a-1); i++)
for (int j = 0; j < sizeof(a-1); j++)
if (a[j].getLitres() > a[j + 1].getLitres())
swap(a[j], a[j + 1]);
cout << a[0] << endl;
CAutomobile k = a[0] + a[3];
cout << k.getLitres() << endl;
【问题讨论】:
关于 Code::Blocks 的重要说明:它不进行编译。它位于第三方编译器之上,通常是 GCC 的一个版本,所以像这样的一些问题需要您追踪正在使用的 g++(GCC 的 C++ 编译器)的版本。通常,您可以通过打开终端窗口并输入g++ -v
来获取此信息。
对于您的构造函数,请尝试使用 CVehicle() : name("Car"), year(1990) ...
等初始化列表。这可能会节省分配默认值。您还需要养成通过引用传递 string
之类的内容的习惯,以避免制作无休止、毫无意义的副本。 const string& arg
是一个很好的默认值。
无关:在setLitres
中,l = litres;
几乎可以肯定是落后的。它将听起来像您想要设置的成员变量分配到一个自动变量中,该变量在函数末尾超出范围而没有任何用处。编译器可能会消除整个函数。可能会有关于此的编译器警告,如果没有,请提高警告级别。编译器警告是防止逻辑错误的第一道防线。
看看这里Programming a specific 3d (star-like) model in OpenGL?它有点像你删除的Question about modelling a specific 3d model?的重复...
【参考方案1】:
CAutomobile::operator =
完全错误。它接受一个非常量引用并将其字段分配给一个新对象。相反,它应该采用 const 引用并修改当前对象。
CAutomobile & operator =(CAutomobile const & other)
assert(this != ::std::addressof(other)); // check for self-assignment
SetName(other.getName());
SetYear(other.getYear());
SetLitres(other.getLitres());
return *this;
这会带来另一个问题:getter 不是 const 限定的,所以它们也应该被修复:
string const & getName(void) const
return name;
int const & getYear(void) const
return year;
【讨论】:
另一个选项是流行的Copy and Swap Idiom,假设复制构造函数正常工作。如果你需要一个赋值运算符,三法则说你可能需要一个复制构造函数。注意:看起来也不需要此代码。 Read up on the Rule of Zero.以上是关于使用赋值运算符 =? 时 C++ 中的编译错误的主要内容,如果未能解决你的问题,请参考以下文章