0

以下のコードに問題があり、コンパイルしますが、出力がデスクトップにクラッシュし、何が間違っているのかを示唆することはありません。

問題は、'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;
}
4

4 に答える 4

3

operator= はオブジェクトへの参照を返す必要があります。現在、何も返されません。何も返さずに非 void 関数から流出するのは未定義の動作です。

Samochod& Samochod::operator = (const Samochod &sam)
        ^^
{
    if(this == &sam)
        return *this;

    marka = sam.marka;
    pojemnosc = 3000;
    przebieg = sam.przebieg;
    return *this;
    ^^^^^^^^^^^^
}
于 2013-05-15T11:16:27.180 に答える
1

含める必要があります<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;
}

また、代入演算子を作成するときに、これが != &rhs であることを確認することも非常に重要です。限られたケースではそれを回避できますが、最終的に後悔することになります。

Samochod& Samochod::operator = (const Samochod &sam)
{
    if(this != &sam)
    {
        marka = sam.marka;
        pojemnosc = 3000;
        przebieg = sam.przebieg;
    }
    return *this;
}

編集:警告レベルを上げて、警告をエラーとして扱う価値があります。これは、古いコード ベースを変換するよりも、警告のないコードを記述する方がはるかに簡単な、従来の奇妙さをあまり必要としない新しい C++ コード ベースでは特に価値があります。このような問題やその他の問題をキャッチします。

于 2013-05-15T11:23:34.030 に答える
0

私が考えることができる 1 つの可能な方法は、テンプレート テンプレート パラメーターです。私の理解が間違っている場合は、ご指摘ください。

于 2013-05-15T12:29:08.780 に答える
0

以下に示すように戻り値の型を変更します

Samochod Samochod::operator = (const Samochod &sam)
{
    return *this;
}
于 2013-05-15T11:51:01.743 に答える