2012-04-08 22 views
5

Próbuję uczyć się C++, a ja przechodzę podstawowe ćwiczenie dotyczące konstruktorów. Mam jeden program, który nieoczekiwanie zachowuje się:C++: Problemy z konstruktorem

Fraction.h:

#include <iostream> 

#ifndef FRACTION_H 
#define FRACTION_H 

using namespace std; 

class Fraction 
{ 
private: 
    int num; 
    int denom; 
    static int gcd(int a, int b); 
    void reduce(); 
public: 
    Fraction(int n=0, int d=1); 
    Fraction(Fraction& f); 
    ~Fraction(); 

    Fraction& operator=(const Fraction& f); 

    friend Fraction operator+(const Fraction& f1, const Fraction& f2); 

    friend ostream& operator<<(ostream& out, const Fraction& f); 
}; 

#endif // FRACTION_H 

Fraction.cpp (niektóre implementacje pominięta):

#include "../include/Fraction.h" 

#include <cassert> 
#include <iostream> 

using namespace std; 

int Fraction::gcd(int a, int b) { 
    // implementation omitted 
} 

void Fraction::reduce() { 
    // implementation omitted 
    // this just reduces fractions to lowest terms, like 3/6 to 1/2 
} 

Fraction::Fraction(int n, int d) { 
    cout << "new fraction, n=" << n << ", d=" << d << endl; 
    assert(d != 0); 
    if (d < 0) { 
     num = -n; 
     denom = -d; 
    } else { 
     num = n; 
     denom = d; 
    } 
    reduce(); 
} 

Fraction::Fraction(Fraction& f) { 
    cout << "copy fraction " << f << " at " << &f << endl; 
    num = f.num; 
    denom = f.denom; 
} 

Fraction::~Fraction() { 
} 

Fraction& Fraction::operator=(const Fraction& f) { 
    cout << "assign fraction to " << f << " at " << &f << endl; 
    if (this == &f) 
     return *this; 
    num = f.num; 
    denom = f.denom; 
    return *this; 
} 

Fraction operator+(const Fraction& f1, const Fraction& f2) { 
    cout << "adding " << f1 << " and " << f2 << endl; 
    return Fraction(f1.num * f2.denom + f2.num * f1.denom, 
        f1.denom * f2.denom); 
} 

ostream& operator<<(ostream& out, const Fraction& f) { 
    out << f.num << "/" << f.denom; 
    return out; 
} 

main.cpp:

#include "include/Fraction.h" 

#include <iostream> 

using namespace std; 

int main() 
{ 
    Fraction f1(1, 3); 
    Fraction f2(1, 2); 
    cout << f1 << endl; 
    cout << f2 << endl; 
    cout << (f1 + f2) << endl; 
    return 0; 
} 

Gdy to uruchomię, pierwsze dwie instrukcje drukowania wyprowadzają 1/3 i 1/2 zgodnie z oczekiwaniami, ale trzecia z nich drukuje 0/1 zamiast . Z posiadanych przeze mnie instrukcji debugowania tworzę 5/6 za pomocą konstruktora Fraction(int, int), ale z jakiegoś powodu zostaje on wywołany z 0/1. Po usunięciu konstruktora kopiowania, kod wypisze 5/6. Co się tutaj dzieje i jak mogę to naprawić bez usuwania konstruktora kopiowania?

+0

Brakuje zbyt wiele kodu odpowiedzialnego za problem. Czy możesz zamieścić resztę kodu lub utworzyć kompletny, kompilowany przykład, który pokazuje problem? –

+1

Hej, tylko z ciekawości - jakiego kompilatora używasz do tego? Chciałbym zobaczyć, w jaki sposób pozwolił na to brakujące 'const' w pierwszej kolejności. –

Odpowiedz

7

Podpis dla konstruktora kopii powinna być

Fraction(const Fraction&); 

nie

Fraction(Fraction&); 

Kiedy robisz return Fraction(...);, kompilator musi zadzwonić Fraction(const Fraction&) ponieważ frakcja zwracane jest tymczasowy, ale ponieważ nie definiujesz tego, twój kompilator robi coś dziwnego. Twój kompilator zachowuje się dziwnie i pozwala ci użyć domyślnego konstruktora, gdy powinien wyrzucić błąd. Kompilowanie kodu w gcc nie działa, musisz dokonać modyfikacji, o której wspomniałem i która powinna to naprawić.

Również fakt, że twój kompilator nie używa RVO w tej funkcji, wskazuje, że używasz bardzo starego i/lub sucky kompilatora.

+0

+1 Po drugie, jest to zdecydowanie odpowiedź. –

+0

Dzięki! Dodanie 'const' sprawiło, że działało. – user1320895

+3

Hi @ user1320895, Widzę, że jesteś nowy w StackOverflow. Ponieważ jesteś pewien, że jest to poprawna odpowiedź, upewnij się, że naciśniesz znacznik wyboru "akceptuj" w tej odpowiedzi, czyli etykieta tutaj. (Mogę być facetem, który ci przypomina, ponieważ nie zamieściłem odpowiedzi :-)). –

Powiązane problemy