2013-02-01 25 views
1

我在C++中編寫了一段代碼,然後決定將其更改爲面向對象和除我的qsort之外的所有函數。我已經擡頭看到它是重載操作員,但我無法弄清楚如何做到這一點。任何人都可以請幫忙?重載運算符以允許qsort在C++中工作

#include <iostream> 
#include <fstream> 
#include <string.h> 
using namespace std; 

class OpAmps { 
private: 
    char Name[20]; 
    unsigned int PinCount; 
    double SlewRate; 
public: 
    void Enter(OpAmps&, unsigned long&); 
    void Save(const OpAmps*, unsigned long); 
    void Load(OpAmps*, unsigned long&); 
    void Sort(OpAmps*, unsigned long); 
    int SortName(const void*, const void*); 
    int SortSlewRate(const void*, const void*); 
    void Display(const OpAmps*, unsigned long); 
}; 

#define DATABASE_MAX 10 
#define DATABASE_FILENAME "database.txt" 

int main() 
{ 
    OpAmps OpAmp[DATABASE_MAX]; 
    OpAmps Menu; 
    unsigned long database_length = 0; 
    char UserInput; 
    while (1) { 
     cout << endl; 
     cout << "Op-amp database menu" << endl; 
     cout << "--------------------" << endl; 
     cout << "1. Enter a new op-amp into the database" << endl; 
     cout << "2. Save the database to disk" << endl; 
     cout << "3. Load the database from disk" << endl; 
     cout << "4. Sort the database" << endl; 
     cout << "5. Display the database" << endl; 
     cout << "6. Exit from the program" << endl << endl; 
     cout << "Enter your option: "; 
     cin >> UserInput; 
     cout << endl; 
     switch(UserInput) { 
      case '1': 
      Menu.Enter(OpAmp[database_length], database_length); 
      break; 
      case '2': 
      Menu.Save(OpAmp, database_length); 
      break; 
      case '3': 
      Menu.Load(OpAmp, database_length); 
      break; 
      case '4': 
      Menu.Sort(OpAmp, database_length); 
      break; 
      case '5': 
      Menu.Display(OpAmp, database_length); 
      break; 
      case '6': 
      return 0; 
      default: 
      cout << "Invalid entry" << endl << endl; 
      break; 
     } 
    } 
} 

void OpAmps::Enter(OpAmps& Op, unsigned long& length) 
{ 
    if (length == DATABASE_MAX) { 
     cout << "The database is full" << endl; 
    } 
    else { 
     cout << "Add new data" << endl; 
     cout << "------------" << endl; 
     cout << "Enter op-amp name: "; 
     cin >> Op.Name; 
     cout << "Enter number of pins: "; 
     cin >> Op.PinCount; 
     cout << "Enter slew rate: "; 
     cin >> Op.SlewRate; 
     cout << endl; 
     length++; 
    } 
} 

void OpAmps::Save(const OpAmps* Op, unsigned long length) 
{ 
    fstream output_file; 
    output_file.open(DATABASE_FILENAME, ios::out); 
    if(output_file.good()) { 
     output_file << length << endl << endl; 
     for (unsigned long i=0;i<length;i++) { 
      output_file << Op[i].Name << endl; 
      output_file << Op[i].PinCount << endl; 
      output_file << Op[i].SlewRate << endl << endl; 
     } 
    } 
    output_file.close(); 
} 

void OpAmps::Load(OpAmps* Op, unsigned long& length) 
{ 
    fstream input_file; 
    input_file.open(DATABASE_FILENAME, ios::in); 
    if(input_file.good()) { 
     input_file >> length; 
     for (unsigned long i=0;i<length;i++) { 
      input_file >> Op[i].Name; 
      input_file >> Op[i].PinCount; 
      input_file >> Op[i].SlewRate; 
     } 
    } 
    input_file.close(); 
} 

void OpAmps::Sort(OpAmps* Op, unsigned long length) 
{ 
    char UserInput; 
    cout << endl; 
    cout << "Sorting options" << endl; 
    cout << "---------------" << endl; 
    cout << "1. To sort by name" << endl; 
    cout << "2. To sort by slew rate" << endl; 
    cout << "3. No sorting" << endl << endl; 
    cout << "Enter your option: "; 
    cin >> UserInput; 
    cout << endl; 
    switch(UserInput) { 
     case '1': 
     cout<<"sortName"<<endl; 
     qsort(Op,length,sizeof(OpAmps),SortName); 
     break; 
     case '2': 
     cout<<"sortslew"<<endl; 
     qsort(Op,length,sizeof(OpAmps),SortSlewRate); 
     break; 
     case '3': 
     return; 
     default: 
     cout << "Invalid entry" << endl << endl; 
     break; 
    } 
} 

int SortName(const void *First, const void* Second) 
{ 
    return strcmp(((OpAmps *) First)->Name, ((OpAmps *) Second)->Name); 
} 

int SortSlewRate (const void *First, const void* Second) 
{ 
    return (int) ((((OpAmps *) First)->SlewRate > ((OpAmps *) Second)->SlewRate)? 1 : -1); 
} 

void OpAmps::Display(const OpAmps* Op, unsigned long length) 
{ 
    if (length == 0) { 
     cout << "No elements in the database" << endl; 
    } 
    else { 
     cout << endl; 
     for (unsigned long i=0;i<length;i++) { 
      cout << "Name: " << Op[i].Name <<endl; 
      cout << "Number of Pins: " << Op[i].PinCount << endl; 
      cout << "Slew Rate: " << Op[i].SlewRate << endl; 
      cout << endl; 
     } 
    } 
} 

乾杯傢伙:d XX

+3

請,請縮進您的代碼。 –

+10

請使用'std :: sort'而不是'qsort'。它幾乎肯定會表現得更好,它將適用於所有常規類型。 –

+3

'qsort'是一個C函數;它不會說運營商超載。代碼以何種方式「不起作用」?無法編譯?產生錯誤的輸出?什麼是預期的輸出? –

回答

2

我認爲在這種情況下,你的問題是,你都用相同的名字定義不同的功能。你已經完成了SortName和SortSlewRate。

一個定義表示「SortName」和「SortSlewRate」是OpAmps類的成員函數,但是在您的代碼中,SortName和SortSlewRate是全局函數。

qsort是一個C函數,它需要函數指針而不是成員函數指針。

既然你的函數是全局函數,但是訪問OpAmps類的私有成員,你應該把'friend'關鍵字放在它們前面。

試着改變你的聲明,這個...

class OpAmps { 
private: 
    char Name[20]; 
    unsigned int PinCount; 
    double SlewRate; 
public: 
    void Enter(OpAmps&, unsigned long&); 
    void Save(const OpAmps*, unsigned long); 
    void Load(OpAmps*, unsigned long&); 
    void Sort(OpAmps*, unsigned long); 
    void Display(const OpAmps*, unsigned long); 

    friend int SortName(const void*, const void*); 
    friend int SortSlewRate(const void*, const void*); 
}; 

所有這一切說,你會更好使用std ::排序,而不是快速排序,你會得到類型安全的優勢,在某些情況下,由於編譯器可以爲您提供優化,所以性能更高。

你的定義是這樣的

class OpAmps { 
private: 
    char Name[20]; 
    unsigned int PinCount; 
    double SlewRate; 
public: 
    void Enter(OpAmps&, unsigned long&); 
    void Save(const OpAmps*, unsigned long); 
    void Load(OpAmps*, unsigned long&); 
    void Sort(OpAmps*, unsigned long); 
    void Display(const OpAmps*, unsigned long); 

    friend bool SortName(const OpAmps &, const OpAmps &); 
    friend bool SortSlewRate(const OpAmps &, const OpAmps &); 
}; 

你可以使用 「排序」 像這樣...

sort(Op, Op + length,SortName); 

sort(Op,Op + length,SortSlewRate); 

注意,排序是一點點不同的,函數返回true(小於)或false(等於或大於)而不是-1(小於),0(等於),-1(大) r比),並且它們不傳遞指針,它們被傳遞給引用。

你會像這樣定義它們。

bool SortName(const OpAmps &First, const OpAmps &Second) 
{ 
    return strcmp(First.Name, Second.Name) < 0; 
} 

bool SortSlewRate (const OpAmps &First, const OpAmps &Second) 
{ 
    return First.SlewRate < Second.SlewRate; 
} 

最後,去更類似於C++,您可以將您的

char Name[20]; 

string Name; 

這將簡化您的SortName功能和反對骯髒的緩衝區溢出漏洞提供的安全性。

bool SortName(const OpAmps &First, const OpAmps &Second) 
{ 
    return First.Name < Second.Name; 
} 
+0

這是偉大的謝謝你,唯一的問題,我現在正在編譯我有這個錯誤: 'sort':不是'std'和'sort'的成員:標識符沒有找到 所以我改變了std我的類OpAmps和排序我的排序,但它提出了這個: 'OpAmps ::排序':函數不需要在每種排序 3參數,這意味着它沒有對數據進行排序。 有什麼幫助嗎? –

+0

@NicoleLeanneBatchelor確保你#include 其中定義了std :: sort,類似#include for std :: string – MerickOWA

+0

非常感謝你!!! –