0

私はC++でコードを記述し、それをオブジェクト指向に変更して、qsort以外のすべての関数を機能させることにしました。演算子のオーバーロードに関係していることを調べましたが、これを行う方法がわかりません。誰か助けてもらえますか?

#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

4

1 に答える 1

1

この場合の問題は、同じ名前の異なる種類の関数を定義していることだと思います。これは、SortNameとSortSlewRateの両方に対して行いました。

1つの定義では、「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*);
};

とはいえ、qsortよりもstd :: sortを使用する方が良いでしょう。型安全性の利点が得られ、場合によっては、コンパイラーが最適化することでさらに高いパフォーマンスが得られます。

あなたの定義は次のようになります

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);

ソートは少し異なり、関数は-1(より小さい)、0(等しい)、-1(より大きい)ではなくtrue(より小さい)またはfalse(等しいまたはより大きい)を返し、それらは'ではないことに注意してください。 t渡されたポインタ、それらは渡された参照です。

あなたはそれらをこのように定義するでしょう。

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;
}
于 2013-02-01T00:14:52.823 に答える