-3

I have been working on this project and I am very close to complete but have one issue with functions saying they are overloaded - any hints would be amazing! Here is my code:

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

class OpAmps 
{
private:
  string Name;
  unsigned int PinCount; 
  double SlewRate; 
public:
  void Enter();
  void Save();
  void Load();
  void Sort();
  void Display();

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

#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();
        break;

        case '2':
        Menu.Save();
        break;

        case '3':
        Menu.Load();
        break;

        case '4':
        Menu.Sort();
        break;

        case '5':
        Menu.Display();
        break;

        case '6':
        return 0;

        default:
        cout << "Invalid entry" << endl << endl;
        break;
    }
}
}

void OpAmps::Enter(OpAmps& Op, unsigned long& database_length)
{
if (database_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;
    database_length++;
}
}

void OpAmps::Save(const OpAmps* Op, unsigned long database_length)
{
fstream output_file;
output_file.open(DATABASE_FILENAME, ios::out);
if(output_file.good()) 
{
    output_file << database_length << endl << endl;
    for (unsigned long i=0;i<database_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& database_length)
{
fstream input_file; 
input_file.open(DATABASE_FILENAME, ios::in);
if(input_file.good()) 
{
    input_file >> database_length;
    for (unsigned long i=0;i<database_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 database_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;
    std::sort(Op, Op + database_length, SortName);
    break;

    case '2':
    cout<<"sortslew"<<endl;
    std::sort(Op,Op + database_length, SortSlewRate);
    break;

    case '3':
    return;
    default:
    cout << "Invalid entry" << endl << endl;
    break;
}
}

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

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

void OpAmps::Display(const OpAmps* Op, unsigned long database_length)
{
if (database_length == 0) 
{
    cout << "No elements in the database" << endl;
}
else 
{
    cout << endl;
    for (unsigned long i=0;i<database_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;
    }
}
}

The errors I am getting are:

error C2511: 'void OpAmps::Enter(OpAmps &,unsigned long &)' : overloaded member     function not found in 'OpAmps'

see declaration of 'OpAmps'

error C2511: 'void OpAmps::Save(const OpAmps *,unsigned long)' : overloaded member function not found in 'OpAmps'

see declaration of 'OpAmps'

error C2511: 'void OpAmps::Load(OpAmps *,unsigned long &)' : overloaded member function not found in 'OpAmps'

see declaration of 'OpAmps'

error C2511: 'void OpAmps::Sort(OpAmps *,unsigned long)' : overloaded member function not found in 'OpAmps'

see declaration of 'OpAmps'

error C2511: 'void OpAmps::Display(const OpAmps *,unsigned long)' : overloaded member function not found in 'OpAmps'

see declaration of 'OpAmps'

Any help would be amazing!! Thanks xx

  • 1
    what particular error message you don't understand? – zaufi Feb 02 '13 at 14:49
  • Your compiler complains because you didn't declare the functions it mentions... – l4mpi Feb 02 '13 at 14:50
  • The `Enter` member doesn't take any argument in the declaration, yet it takes argument in the definition. That is a LIE, isn't? – Nawaz Feb 02 '13 at 14:50
  • Every member function **must** be declared in the class definition. You did not declare any of the overloaded versions in class definition. Unless you declare the functions the compiler cannot know they belong to the class and hence the compiler gives you appropriate diagnostic message. – Alok Save Feb 02 '13 at 14:51
  • you forget to mention the parameters in methods. – Arpit Feb 02 '13 at 14:51
  • I don't know how to solve these issues - any idea where or how I would declare the function? I am very new to C++ and unsure how to to overload or solve these isssues. – Nicole Leanne Batchelor Feb 02 '13 at 14:52
  • 1
    You forgotten about the methods arguments in the declaration of the class. – yattering Feb 02 '13 at 14:53
  • 2
    You definitely need a [good book](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) to begin with. – Alok Save Feb 02 '13 at 14:54
  • 1
    Note that you don't need the first argument for these functions. These are (non-static) member functions, so they *always* refer to an instance they are called on. `Menu.Load()` for example is called *on the instance `Menu`* which means, when you for example write `Name`, this always refers to `Menu.Name`. *static* member functions (by putting `static` in front of the signature) are used as you want them to be used (not operating on an instance). – leemes Feb 02 '13 at 14:56
  • @leemes No, she does! The first pointer param to member-functions isn't an (`this`) instance actually, but pointer to array w/ size as second param... @NicoleLeanneBatchelor You definitely ought rethink your design (after reading a good book(s)) – zaufi Feb 02 '13 at 15:00
  • Please could someone give me an example of the above comment from @leemes regarding the use of "static"? – Nicole Leanne Batchelor Feb 02 '13 at 15:00
  • @zaufi You're right. In this case, these functions (the ones which operate on arrays) should be defined *outside* the class and use smaller functions operating on single instances, like "load one single entry from a file". So no need for `static`. – leemes Feb 02 '13 at 15:04
  • so @NicoleLeanneBatchelor respobses below wouldn't fix your problem w/ design! – zaufi Feb 02 '13 at 15:08

5 Answers5

2

You declared the functions with one signature, for example:

void Enter();

but then you implemented them with another:

void OpAmps::Enter(OpAmps& Op, unsigned long& database_length)

The function signatures must match between declaration and definition. You are allowed to implement several functions with the same name but different signatures and that is called "overloading", but in this case, you're providing overloads that you never declare, and declare functions you never implement.

Though I don't understand why you need the function arguments to begin with. The functions look like they want to work on the OpAmps object they're called on. So why pass an OpAmps as an argument? Are you sure you don't mean to work on the this object instead? this is a pointer to the object a member function is called on. For example:

cin >> this->Name;
Nikos C.
  • 50,738
  • 9
  • 71
  • 96
  • So if I declare the original as void Enter(OpAmps&, unsigned long&); – Nicole Leanne Batchelor Feb 02 '13 at 14:55
  • @NicoleLeanneBatchelor Then it will work. Though I don't understand why you need the function arguments to begin with. The functions look like they want to work on the OpAmps object they're called on. So why pass an OpAmps as an argument? Are you sure you don't mean to work on the `this` object instead? (`this` is a pointer to the object a member function is called on.) – Nikos C. Feb 02 '13 at 14:57
  • Would this be for all instances of Op or just some of them? – Nicole Leanne Batchelor Feb 02 '13 at 15:07
  • @NicoleLeanneBatchelor For the instance you call the function on. You cannot call a non-static member function without an instance. `this` will always point to the instance the function is called on. – Nikos C. Feb 02 '13 at 15:13
1

You declare your functions as taking no arguments:

void Enter();
void Save();
void Load();
void Sort();
void Display();

But then you define them as taking arguments:

void OpAmps::Enter(OpAmps& Op, unsigned long& database_length)
{
     ...
}

void OpAmps::Save(const OpAmps* Op, unsigned long database_length)
{
     ...
}

And so on. The compiler cannot match those definitions to any declaration, so it issues those error messages.

To fix this, change your class definition as follows:

class OpAmps
{
private:
    string Name;
    unsigned int PinCount;
    double SlewRate;
public:
    void Enter(OpAmps& Op, unsigned long& database_length);
    void Save(OpAmps const* Op, unsigned long& database_length);
    void Load(OpAmps* Op, unsigned long& database_length);
    void Sort(OpAmps* Op, unsigned long& database_length);
    void Display(OpAmps const* Op, unsigned long& database_length);

    friend bool SortName(const OpAmps &, const OpAmps &);
    friend bool SortSlewRate(const OpAmps &, const OpAmps &);
};
Andy Prowl
  • 124,023
  • 23
  • 387
  • 451
1

You prototype this function:

void Enter();

And then you implemented it as:

void OpAmps::Enter(OpAmps& Op, unsigned long& database_length)

Which doesn't make sense in the slightest.

Either change the signature, or the implementation, and I think that in this case you'd be better off changing the signature.

But even then, I don't think the first OpAmps& parameter in the implementation is necessary. You should use this. So change the method prototype into:

void Enter(unsigned long&);

And the implementation into:

void OpAmps::Enter(unsigned long& database_length)

And change any use of the unnecessary op parameter with the this keyword. The same holds for any OpAmps::? function you're not prototyping/implementing correctly.

The reason for this is because the functions you're declaring are non-static member functions, meaning they always belong to an instance. You don't need to pass the instance to the method like you would in C, instead you can use the instance the method is called on to with the this keyword. The this keyword is a constant pointer to the instance the method is called on (in your case that would be a pointer to Menu).

You could therefore use:

cin >> this->Name;

Instead of:

cin >> op.Name;

However, in this case, it's unnecessary to use the this keyword. The C++ will figure out itself whether the field/function is instance-bound or not:

cin >> Name;
antonijn
  • 5,702
  • 2
  • 26
  • 33
0

The signatures of your function class declarations differ from the signature of the implemented versions. They must be the same. So change:

void Enter();

to

Enter(OpAmps &, unsigned long &);

And all other instances where you do this.

David G
  • 94,763
  • 41
  • 167
  • 253
0

replace your method prototypes with the following :

void Enter(OpAmps& Op, unsigned long& database_length);
  void Save(OpAmps& Op, unsigned long& database_length);
  void Load(OpAmps& Op, unsigned long& database_length);
  void Sort(OpAmps& Op, unsigned long& database_length);
  void Display(OpAmps& Op, unsigned long& database_length);
Arpit
  • 12,767
  • 3
  • 27
  • 40