[英]Overload resolution on extern “C” and “C++” version of qsort()/bsearch()
[英]Overload operators to allow qsort to work in C++
我用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
我認為在這種情況下,您的問題是您使用相同的名稱定義了不同種類的函數。 您已經對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 :: sort而不是qsort會更好,您將獲得類型安全的優勢,並且在某些情況下,由於編譯器可以為您進行優化,因此性能更高。
您的定義如下所示
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(大於),它們不是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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.