问题描述:

I have a problem with below code, it compiles, yet the output crashes to desktop without giving me any suggestion what i'm doing wrong.

I know the problem is within operator= overloading at 'Ciezarowy::operator = (const Samochod &sam)' and its executed at

'ciezar[0] = samochody[0];'

Sorry for long main() but i'm doing it for learning purpose so i want to see result for all actions.

here's the code, compiled by 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;

}

网友答案:

Your operator= should return a reference to the object. Right now it doesn't return anything. It is Undefined Behavior to flow out of a non void function without returning anything.

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

    marka = sam.marka;
    pojemnosc = 3000;
    przebieg = sam.przebieg;
    return *this;
    ^^^^^^^^^^^^
}
网友答案:

You need to include <string>

Your assignment operators must return something or this is undefined behavoir

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

Its traditional to return a reference

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

Its also pretty much imperative to check that this != &rhs when you're writing assignment operators. You can get away with it in limited cases but you'll eventually regret it.

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

EDIT: Its well worth cranking the warning level up and treating warnings as errors. This is especially worth it in new C++ code bases where you don't need a lot of the legacy weirdness - its much easier to write warning free code than it is to convert an old code base to it. It would catch issues like this and a whole lot more.

网友答案:

change the return type as shown below

Samochod Samochod::operator = (const Samochod &sam)
{
    return *this;
}
网友答案:

One possible way i could think of is template template parameters. All, kindly point out if my understanding is incorrect.

相关阅读:
Top