重载操作符=,不同的类作为参数
overload operator=, different class as argument
我有一个问题,下面的代码,它编译,但输出崩溃到桌面没有给我任何建议,我做错了。
我知道问题是在'Ciezarowy::operator = (const Samochod &sam)'的operator=重载内,并且它在'ciezar[0] = samochody[0];'
很抱歉长main(),但我这样做是为了学习的目的,所以我想看到所有动作的结果。
下面是代码,由CodeBlocks/MinGW编译。#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
class Samochod{
public:
string marka;
int pojemnosc;
double przebieg;
Samochod();
Samochod operator = (const Samochod &sam);
Samochod(const Samochod &sam);
};
Samochod::Samochod()
{
string marki[5] = {"Opel","Audi","Toyota","Fiat","Mazda"};
int index = rand() % 5;
marka = marki[index];
pojemnosc = rand() % 2000 + 1200;
przebieg = 40000;
}
Samochod Samochod::operator = (const Samochod &sam)
{
marka = sam.marka;
pojemnosc = 3000;
przebieg = sam.przebieg;
}
Samochod::Samochod(const Samochod &sam)
{
marka = sam.marka;
pojemnosc = 3000;
przebieg = sam.przebieg;
}
class Osobowy:public Samochod
{
public:
Osobowy();
int lpas;
double pojb;
int ldrzwi;
};
Osobowy::Osobowy()
: lpas( 5 )
, pojb( rand() % 100 + 80 )
, ldrzwi ( 5 )
{
}
class Ciezarowy:public Samochod
{
public:
Ciezarowy();
int losi;
double ladownosc;
bool samow;
Ciezarowy operator = (const Samochod &sam);
};
Ciezarowy::Ciezarowy()
: losi ( rand() % 2 + 2 )
, ladownosc ( 1000 )
, samow ( 1 )
{
}
Ciezarowy Ciezarowy::operator = (const Samochod &sam)
{
marka = sam.marka;
przebieg = sam.przebieg;
}
int main()
{
srand( time( NULL ) );
Samochod samochody[4];
Samochod samoch[3];
for ( int i = 0;i<3;i++){
samoch[i] = samochody[i];}
cout<<samochody[0].marka<<endl;
cout<<samochody[0].pojemnosc<<endl;
cout<<samochody[0].przebieg<<endl;
cout<<samochody[1].marka<<endl;
cout<<samochody[1].pojemnosc<<endl;
cout<<samochody[1].przebieg<<endl;
cout<<samochody[2].marka<<endl;
cout<<samochody[2].pojemnosc<<endl;
cout<<samochody[2].przebieg<<endl;
cout<<samochody[3].marka<<endl;
cout<<samochody[3].pojemnosc<<endl;
cout<<samochody[3].przebieg<<endl;
cout<<samoch[0].marka<<endl;
cout<<samoch[0].pojemnosc<<endl;
cout<<samoch[0].przebieg<<endl;
cout<<samoch[1].marka<<endl;
cout<<samoch[1].pojemnosc<<endl;
cout<<samoch[1].przebieg<<endl;
cout<<samoch[2].marka<<endl;
cout<<samoch[2].pojemnosc<<endl;
cout<<samoch[2].przebieg<<endl;
Osobowy osob[3];
osob[1].ldrzwi = 3;
osob[1].lpas = 4;
cout<<osob[0].marka<<endl;
cout<<osob[0].pojemnosc<<endl;
cout<<osob[0].przebieg<<endl;
cout<<osob[0].ldrzwi<<endl;
cout<<osob[0].lpas<<endl;
cout<<osob[0].pojb<<endl;
cout<<osob[1].marka<<endl;
cout<<osob[1].pojemnosc<<endl;
cout<<osob[1].przebieg<<endl;
cout<<osob[1].ldrzwi<<endl;
cout<<osob[1].lpas<<endl;
cout<<osob[1].pojb<<endl;
cout<<osob[2].marka<<endl;
cout<<osob[2].pojemnosc<<endl;
cout<<osob[2].przebieg<<endl;
cout<<osob[2].ldrzwi<<endl;
cout<<osob[2].lpas<<endl;
cout<<osob[2].pojb<<endl;
Ciezarowy ciezar[2];
ciezar[0] = samochody[0];
ciezar[1].ladownosc = 500;
ciezar[1].samow = 0;
cout<<ciezar[0].marka<<endl;
cout<<ciezar[0].pojemnosc<<endl;
cout<<ciezar[0].przebieg<<endl;
cout<<ciezar[0].losi<<endl;
cout<<ciezar[0].ladownosc<<endl;
cout<<ciezar[0].samow<<endl;
cout<<ciezar[1].marka<<endl;
cout<<ciezar[1].pojemnosc<<endl;
cout<<ciezar[1].przebieg<<endl;
cout<<ciezar[1].losi<<endl;
cout<<ciezar[1].ladownosc<<endl;
cout<<ciezar[1].samow<<endl;
return 0;
}
操作符=应该返回对该对象的引用。现在它没有返回任何东西。未定义行为从非void函数流出而不返回任何东西。
Samochod& Samochod::operator = (const Samochod &sam)
^^
{
if(this == &sam)
return *this;
marka = sam.marka;
pojemnosc = 3000;
przebieg = sam.przebieg;
return *this;
^^^^^^^^^^^^
}
您需要包含<string>
你的赋值操作符必须返回一些东西,否则这是未定义的行为
Samochod Samochod::operator = (const Samochod &sam)
{
marka = sam.marka;
pojemnosc = 3000;
przebieg = sam.przebieg;
return *this;
}
传统上返回一个引用
Samochod& Samochod::operator = (const Samochod &sam)
{
marka = sam.marka;
pojemnosc = 3000;
przebieg = sam.przebieg;
return *this;
}
在编写赋值操作符时,检查this != &rhs也是非常必要的。在有限的情况下你可以侥幸逃脱,但你最终会后悔的。
Samochod& Samochod::operator = (const Samochod &sam)
{
if(this != &sam)
{
marka = sam.marka;
pojemnosc = 3000;
przebieg = sam.przebieg;
}
return *this;
}
编辑:将警告级别调高并将警告视为错误是非常值得的。这在新的c++代码库中是特别值得的,因为你不需要很多遗留的怪异之处——编写无警告代码比将旧代码库转换为无警告代码要容易得多。它可以捕获像这样的问题,以及更多的问题。
更改返回类型,如下所示
Samochod Samochod::operator = (const Samochod &sam)
{
return *this;
}
我能想到的一种可能的方法是模板模板参数。如果我的理解不正确,请指出来。
相关文章:
- 我可以将C 17 Capture lambda ConstexPR转换操作符的结果用作函数指针模板非类型参数吗?
- 单参数构造函数和赋值操作符
- c++中的操作符重载,无法调用双参数构造函数
- 操作符重载模板参数
- c++操作符重载以指针类型作为参数
- 在覆盖new操作符时传递更多参数(c++)
- 带有不同参数的c++操作符重载模板
- 重载操作符=,不同的类作为参数
- 如何检查类型是否存在无参数操作符()
- 传递静态方法作为参数,不需要地址操作符
- 检索对象的函数操作符的参数类型
- 带有派生类型参数的赋值操作符
- 使用具有不同参数的相同操作符
- 为什么小于操作符接受不同类型的参数,而std::min不接受
- 将构造函数参数转发给放置new操作符
- (为什么)移动构造函数或移动赋值操作符应该清除其参数
- 对操作符()()中具有状态和两个参数的函数对象使用boost绑定
- 比较测试失败:unorder_map上的[]操作符产生的参数数量错误
- 操作符重载和不同的模板参数
- c++如何确定重载操作符的参数