2012-06-26 3 views
-1

Я получил этот ожидаемый конструктор, деструктор или преобразование типа перед маркером «&», когда я выполнил запуск оператора. Ошибки произошли в последних 8 строках fixed.cpp. Я не уверен, что я пропустил. Любая помощь приветствуется.С ++ ожидаемый конструктор, деструктор или преобразование типа перед токеном «&»

Это fixed.hpp

#ifndef FIXED_HPP_ 
    #define FIXED_HPP_ 

    typedef float value_type ; 

    class fixed 
    { 
    public: 
     fixed(); 
     fixed(value_type integer, value_type fraction); 
     fixed(double val); 
     void as_string(); 
     value_type integer(); 
     value_type fraction(); 
     value_type value(); 
     //~fixed(); 
     fixed& operator+=(fixed other); 

     static const int places=4; 
     static const int places10=10000; 

    private: 
     value_type integer_; 
     value_type fraction_; 
     value_type value_; 
    }; 

    fixed operator+(fixed a, fixed b); 

    #endif 

Это fixed.cpp:

#include "fixed.hpp" 

    #include <iostream> 
    #include <ostream> 
    #include <stdexcept> 
    #include <string> 
    #include <algorithm> 


    using namespace std; 

    fixed::fixed():integer_(0), fraction_(0), value_(0){} 

    fixed::fixed(value_type integer, value_type     fraction):integer_(integer),   fraction_(fraction) 
      {try 
     { 
     if (fraction_ <0)       
      throw invalid_argument("Invalid argument. Must be positive."); 
     } 
      catch (exception& e) 
       { 
       cout <<"\n"<< e.what() << std::endl; 
     } 
      while (fraction_>= places10) 
       { 
       if(int(fraction_)%10 >=5 && fraction_< (places10*10)) 
      fraction_=int(fraction_/10+1);    
     else 
      fraction_ =int(fraction_/10); 
     } 

    value_ = integer_*places10 + fraction_; 
      } 

    fixed::fixed(double val):integer_(int (val)), fraction_((val- int(val))*places10) 
      { if (val <0) 
       { val = val*(-1); 
      if (int(val*places10*10)%10>=5) 
       fraction_ = (fraction_*(-1) +1)*(-1); 
     }  
    else 
     { 
      if (int(val*places10*10)%10>=5) 
       fraction_ = fraction_ +1; 
     } 

    value_ = integer_*places10 + fraction_; 
      } 

    void fixed::as_string() 
      { string str; 
       string str2; 
     while((int(integer_)/10) >=0 and int(integer_)>0) 
      { 
      str.push_back(int(integer_)%10 + 48); 
      integer_ = integer_/10; 
      //cout<<str<<endl; 
      } 
     //cout<<"String format: "<<str<<endl; 
     reverse(str.begin(), str.end()); 
     //cout<<"Reversed format: "<<str<<endl; 
     str.push_back('.'); 
     //cout<<"New string: "<<str<<endl; 
     while((int(fraction_)/10)>=0 and int(fraction_)>0) 
      { 
      str2.push_back(int(fraction_)%10 + 48); 
      fraction_ = fraction_/10; 
      //cout<<str<<endl; 
      } 
     //cout<<"String format: "<<str<<endl; 
     reverse(str2.begin(), str2.end()); 
     str.append(str2); 
     cout<<"String representation: "<<str<<endl; 
      } 

    value_type fixed::value() 
     { 
      return value_;  
     } 
    value_type fixed::integer() 
     { 
      return integer_; 
     } 
    value_type fixed::fraction() 
       { 
      return fraction_; 
     } 
    fixed& fixed::operator+=(fixed other) // error 
      { value_ += other.value(); 
      return *this;  
      } 

    fixed operator+(fixed a, fixed b) //error 
      { a+=b; 
      return a;} 
+2

К сожалению, многие книги, учебные пособия и т. Д. Использовали 'using namespace std;' для сокращения кода, но это приводит к проблемам (как в вашем примере) и не должно использоваться. –

+0

Эта проблема [была идентифицирована уже] (http://stackoverflow.com/q/11158258/1214731). Есть ли причина, по которой вы все еще используете 'namespace std'? – tmpearce

ответ

4

Ваш код имеет много проблем. Основная проблема ниже:

fixed является членом namespace std; вы объявляете одно и то же имя class и имеете злой using namespace std; в своем коде.

Несколько других точек:

  1. Всегда, сделать практику неusing namespace std на глобальном области. Поместите std:: префикс, если необходимо, или поместите using внутри области .
  2. fixed::operator+=(Fixed), должно быть fixed::operator+=(const Fixed&); иначе он сделает ненужную копию.
  3. Выше комментарий для operator+(fixed a, fixed b) также и кроме того, a += b, что не так. Она должна быть простой a + b эквивалент
+0

Вот [демо-код после некоторых исправлений] (http://ideone.com/iCe8D). – iammilind

2

Clang предоставляет следующую ошибку, которая должна сделать его более очевидным, что происходит:

fixed.cpp:90:1: error: reference to 'fixed' is ambiguous 
fixed& fixed::operator+=(fixed other) // error 
^ 
./fixed.hpp:6:11: note: candidate found by name lookup is 'fixed' 
    class fixed 
     ^
/usr/include/c++/4.2.1/bits/ios_base.h:950:3: note: candidate found by name lookup is 'std::fixed' 
    fixed(ios_base& __base) 
^
2

Это классический пример того, почему вы не должны использовать using namespace std;, вы вызываете что-то называемое загрязнением пространства имен, имея одинаковые идентификаторы в одном и том же пространстве имен (поскольку все из std было втянуто).

Прежде всего, вытяните части пространства имен std только тогда, когда они вам понадобятся using std::something;. Или еще лучше, научитесь ценить std::, это сделает вашу жизнь намного легче, когда вы поправляетесь на C++, который живет и дышит своей стандартной библиотекой.

Во-вторых, много вашего кода катастрофично, когда учитывается стиль, не говоря уже о плохих практиках. Вы вводя такие вещи, как:

fixed& operator+=(fixed other); 

Существует много проблем с этим, но наиболее известными из них является отсутствие константности и тот факт, что вы на самом деле проходите экземпляр класса по значению, вызывая конструктор копирования и создание ненужного дубликата. Причина, по которой вам нужно использовать const, - это проблема безопасности программиста и хорошая практика. Видите ли, вам нужно только прочитать входящее значение, чтобы сформулировать ответ, возврат оператора. Поэтому, делая его неизменным, вы можете безопасно вычислять результат и возвращать его.

fixed& operator+=(const fixed& other); // preferably call *other* rhs (righthandside) 

При удалении using namespace std; или изменить название своего класса в целом, ваши первоначальные проблемы исчезнут. Но в ваших операционных перегрузках много чего не так. В частности, как вы принимаете параметры, как вы их возвращаете и управляете ситуацией, чтобы делать только то, что действительно нужно (избегая ненужных копий и временных рядов).

Смежные вопросы

 Смежные вопросы