473,326 Members | 2,023 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,326 software developers and data experts.

Classes and structures

I have a structured piece of code that i am converting into object orientated, the structured code contains a stuct;


Expand|Select|Wrap|Line Numbers
  1. struct OpAmps {
  2.   char Name[20];  // the name of the op-amp (e.g. "741")
  3.   unsigned int PinCount;  // the number of pins in the package
  4.   double SlewRate;  // the slew rate in volts per microsecond
  5. };

This struct needs to be included in the OO code as it is a part of the functions - now member functions.

So far the class i have defined for the OO code is;

Expand|Select|Wrap|Line Numbers
  1. class OpAmpDb
  2. {
  3. public:
  4.     OpAmpDb();
  5.     void Enter(OpAmps&, unsigned long&);
  6.     void Save(const OpAmps*, unsigned long);
  7.     void Load(OpAmps*, unsigned long&);
  8.     void Sort(OpAmps*, unsigned long);
  9.     int SortName(const void*, const void*);
  10.     int SortSlewRate(const void*, const void*);
  11.     void Display(const OpAmps*, unsigned long);
  12. private:
  13.     int Num;
  14. };
  15.  
Problem - the constructor is not working properly, i define the member function;

OpAmpDb::OpAmpDb()


and get an error that i cannot redeclare it! I am very confused about this, not quite sure where to put my struct definition in the new OO code or why my constructor will not work!!

Please help!!
May 5 '07 #1
10 2092
AdrianH
1,251 Expert 1GB
Given the limited amount of information you have posted, I would say that you are defining the body of OpAmpDb::OpAmpDb() in the header file. I could be wrong though. But in the off chance I am correct, but the function definition in a source file.

If I am wrong, it may help if you post the error messages being emitted from the comipler.


Adrian
May 5 '07 #2
I have 2 header files and one cpp file.

object.h contains;

Expand|Select|Wrap|Line Numbers
  1. struct OpAmps {
  2.   char Name[20];  // the name of the op-amp (e.g. "741")
  3.   unsigned int PinCount;  // the number of pins in the package
  4.   double SlewRate;
  5. };
  6.  
  7. class OpAmpDb
  8. {
  9. public:
  10.     OpAmpDb();
  11.     void Enter(OpAmps&, unsigned long&);
  12.     void Save(const OpAmps*, unsigned long);
  13.     void Load(OpAmps*, unsigned long&);
  14.     void Sort(OpAmps*, unsigned long);
  15.     int SortName(const void*, const void*);
  16.     int SortSlewRate(const void*, const void*);
  17.     void Display(const OpAmps*, unsigned long);
  18. private:
  19.     int Num;
  20. };


memfun contains;


Expand|Select|Wrap|Line Numbers
  1. OpAmpDb::OpAmpDb();
  2. {
  3.     OpAmpObject OpAmp[DATABASE_MAX];
  4.     unsigned long database_length = 0;  // the number of elements in the database
  5.     char UserInput;
  6.  
  7.   // loop until the user wishes to exit
  8.   while (1) {
  9.  
  10.     // show the menu of options
  11.     cout << endl;
  12.     cout << "Op-amp database menu" << endl;
  13.     cout << "--------------------" << endl;
  14.     cout << "1. Enter a new op-amp into the database" << endl;
  15.     cout << "2. Save the database to disk" << endl;
  16.     cout << "3. Load the database from disk" << endl;
  17.     cout << "4. Sort the database" << endl;
  18.     cout << "5. Display the database" << endl;
  19.     cout << "6. Exit from the program" << endl << endl;
  20.  
  21.     // get the user's choice
  22.     cout << "Enter your option: ";
  23.     cin >> UserInput;
  24.     cout << endl;
  25.  
  26.     // act on the user's input
  27.     switch(UserInput) {
  28.       case '1':
  29.           OpAmpObject.Enter(OpAmp[database_length], database_length);
  30.         break;
  31.  
  32.       case '2':
  33.           OpAmpObject.Save(OpAmp, database_length);
  34.         break;
  35.  
  36.       case '3':
  37.           OpAmpObject.Load(OpAmp, database_length);
  38.         break;
  39.  
  40.       case '4':
  41.           OpAmpObject.Sort(OpAmp, database_length);
  42.         break;
  43.  
  44.       case '5':
  45.           OpAmpObject.Display(OpAmp, database_length);
  46.         break;
  47.  
  48.       case '6':
  49.         return 0;
  50.  
  51.       default:
  52.         cout << "Invalid entry" << endl << endl;
  53.         break;
  54.     }
  55.   }
  56. }
including other member function definitions. the cpp file contains;


Expand|Select|Wrap|Line Numbers
  1. #include <stdafx.h>
  2. #include <iostream>
  3. #include <fstream>
  4. #include <string.h>
  5. #include "object.h"
  6. #include "MemFun.h"
  7.  
  8.  
  9. int main()
  10. {
  11.     OpAmpDb OpAmpObject;
  12.  
  13.     return 0;
  14. }

It does not like that ive put all the member functions into another file, and it still says that i cannot redefine the member function

error C2761 '{ctor}' : member function redelaration not allowed
May 5 '07 #3
AdrianH
1,251 Expert 1GB
Expand|Select|Wrap|Line Numbers
  1. OpAmpDb::OpAmpDb();
  2. {
  3.     OpAmpObject OpAmp[DATABASE_MAX];
  4.     unsigned long database_length = 0;  // the number of elements in the database
  5. //...
  6. }
including other member function definitions. the cpp file contains;

(snip)

It does not like that ive put all the member functions into another file, and it still says that i cannot redefine the member function

error C2761 '{ctor}' : member function redelaration not allowed
Ahh, I see the problem. It is a redelaration error, not a redefinition error. You have a semicolon after OpAmpDb::OpAmpDb() so the compiler thinks you are trying to redeclare it. That is not allowed. Get rid of the semicolon and it should work.


Adrian

P.S. When stating an error, you may wish to post all of the error/warning messages (or at least the first 2-5). It may help in debugging the problem.
May 5 '07 #4
Thank you! so i changed that, and now im having problems with the fact that the object im creating is being converted from a struct to object oriented, except, im not sure how to do this and all the errors are related to the fact that in the menu code the left of .Enter, .Save etc are not class/struct/union! also i have an error that says that OpAmpObject is undeclared, except ive created it in main from the OpAmpDb class;

Expand|Select|Wrap|Line Numbers
  1. int main()
  2. {
  3.     OpAmpDb OpAmpObject;
  4.  
  5.     return 0;
  6. }
  7.  
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14. #define DATABASE_FILENAME "database.txt"
  15.  
  16. #define DATABASE_MAX 10
  17.  
  18. OpAmpDb::OpAmpDb()
  19. {
  20.     unsigned long database_length = 0;  // the number of elements in the database
  21.     char UserInput;
  22.  
  23.   // loop until the user wishes to exit
  24.   while (1) {
  25.  
  26.     // show the menu of options
  27.     cout << endl;
  28.     cout << "Op-amp database menu" << endl;
  29.     cout << "--------------------" << endl;
  30.     cout << "1. Enter a new op-amp into the database" << endl;
  31.     cout << "2. Save the database to disk" << endl;
  32.     cout << "3. Load the database from disk" << endl;
  33.     cout << "4. Sort the database" << endl;
  34.     cout << "5. Display the database" << endl;
  35.     cout << "6. Exit from the program" << endl << endl;
  36.  
  37.     // get the user's choice
  38.     cout << "Enter your option: ";
  39.     cin >> UserInput;
  40.     cout << endl;
  41.  
  42.     // act on the user's input
  43.     switch(UserInput) {
  44.       case '1':
  45.           OpAmpObject.Enter(OpAmp[database_length], database_length);
  46.         break;
  47.  
  48.       case '2':
  49.           OpAmpObject.Save(OpAmp, database_length);
  50.         break;
  51.  
  52.       case '3':
  53.           OpAmpObject.Load(OpAmp, database_length);
  54.         break;
  55.  
  56.       case '4':
  57.           OpAmpObject.Sort(OpAmp, database_length);
  58.         break;
  59.  
  60.       case '5':
  61.           OpAmpObject.Display(OpAmp, database_length);
  62.         break;
  63.  
  64.       case '6':
  65.         return 0;
  66.  
  67.       default:
  68.         cout << "Invalid entry" << endl << endl;
  69.         break;
  70.     }
  71.   }
  72. }
May 5 '07 #5
ilikepython
844 Expert 512MB
Thank you! so i changed that, and now im having problems with the fact that the object im creating is being converted from a struct to object oriented, except, im not sure how to do this and all the errors are related to the fact that in the menu code the left of .Enter, .Save etc are not class/struct/union! also i have an error that says that OpAmpObject is undeclared, except ive created it in main from the OpAmpDb class;

Expand|Select|Wrap|Line Numbers
  1. int main()
  2. {
  3.     OpAmpDb OpAmpObject;
  4.  
  5.     return 0;
  6. }
  7.  
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14. #define DATABASE_FILENAME "database.txt"
  15.  
  16. #define DATABASE_MAX 10
  17.  
  18. OpAmpDb::OpAmpDb()
  19. {
  20.     unsigned long database_length = 0;  // the number of elements in the database
  21.     char UserInput;
  22.  
  23.   // loop until the user wishes to exit
  24.   while (1) {
  25.  
  26.     // show the menu of options
  27.     cout << endl;
  28.     cout << "Op-amp database menu" << endl;
  29.     cout << "--------------------" << endl;
  30.     cout << "1. Enter a new op-amp into the database" << endl;
  31.     cout << "2. Save the database to disk" << endl;
  32.     cout << "3. Load the database from disk" << endl;
  33.     cout << "4. Sort the database" << endl;
  34.     cout << "5. Display the database" << endl;
  35.     cout << "6. Exit from the program" << endl << endl;
  36.  
  37.     // get the user's choice
  38.     cout << "Enter your option: ";
  39.     cin >> UserInput;
  40.     cout << endl;
  41.  
  42.     // act on the user's input
  43.     switch(UserInput) {
  44.       case '1':
  45.           OpAmpObject.Enter(OpAmp[database_length], database_length);
  46.         break;
  47.  
  48.       case '2':
  49.           OpAmpObject.Save(OpAmp, database_length);
  50.         break;
  51.  
  52.       case '3':
  53.           OpAmpObject.Load(OpAmp, database_length);
  54.         break;
  55.  
  56.       case '4':
  57.           OpAmpObject.Sort(OpAmp, database_length);
  58.         break;
  59.  
  60.       case '5':
  61.           OpAmpObject.Display(OpAmp, database_length);
  62.         break;
  63.  
  64.       case '6':
  65.         return 0;
  66.  
  67.       default:
  68.         cout << "Invalid entry" << endl << endl;
  69.         break;
  70.     }
  71.   }
  72. }
You can't use an instance of a class in the class itself by the name of the instance. You just call the function without adding the "OpAmpObject.":
Expand|Select|Wrap|Line Numbers
  1. Enter(arguements);
  2. Save(arguements);
  3.  
Also, the "this" keyword refers to the instance the class is called with.
May 5 '07 #6
AdrianH
1,251 Expert 1GB
Thank you! so i changed that, and now im having problems with the fact that the object im creating is being converted from a struct to object oriented, except, im not sure how to do this and all the errors are related to the fact that in the menu code the left of .Enter, .Save etc are not class/struct/union! also i have an error that says that OpAmpObject is undeclared, except ive created it in main from the OpAmpDb class;

Expand|Select|Wrap|Line Numbers
  1. int main()
  2. {
  3.     OpAmpDb OpAmpObject;
  4.  
  5.     return 0;
  6. }
  7.  
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14. #define DATABASE_FILENAME "database.txt"
  15.  
  16. #define DATABASE_MAX 10
  17.  
  18. OpAmpDb::OpAmpDb()
  19. {
  20.     unsigned long database_length = 0;  // the number of elements in the database
  21.     char UserInput;
  22.  
  23.   // loop until the user wishes to exit
  24.   while (1) {
  25.  
  26.     // show the menu of options
  27.     cout << endl;
  28.     cout << "Op-amp database menu" << endl;
  29.     cout << "--------------------" << endl;
  30.     cout << "1. Enter a new op-amp into the database" << endl;
  31.     cout << "2. Save the database to disk" << endl;
  32.     cout << "3. Load the database from disk" << endl;
  33.     cout << "4. Sort the database" << endl;
  34.     cout << "5. Display the database" << endl;
  35.     cout << "6. Exit from the program" << endl << endl;
  36.  
  37.     // get the user's choice
  38.     cout << "Enter your option: ";
  39.     cin >> UserInput;
  40.     cout << endl;
  41.  
  42.     // act on the user's input
  43.     switch(UserInput) {
  44.       case '1':
  45.           OpAmpObject.Enter(OpAmp[database_length], database_length);
  46.         break;
  47. //...
  48.     }
  49.   }
  50. }
You havn't programmed in C++ before, have you.

Scoping rules state that a variable/object declared in another scope is not accessable unless that scope you are accessing from is contained within the scope you are accessing. So:
Expand|Select|Wrap|Line Numbers
  1. void fn2()
  2. {
  3.   bar = 3;
  4. }
  5.  
  6. void fn1()
  7. {
  8.   int bar = 4;
  9.   fn2();
  10. }
  11.  
will not work for the same reason that your code will not work. They are in seperate scopes. (a scope is roughly defined as being encompassed by braces, but need not be in the case of the body of a for/if/while/do. In those cases, the new scope is implicit).

In your case, you just want to access the 'this' object. The object that the member function belongs to.

A class has a special type of scope. If you are within a member function of the class, all members are accessable as if they were defined in the global scope (roughly anyway). So:
Expand|Select|Wrap|Line Numbers
  1. class A
  2. {
  3.   int variable;
  4.   A();
  5.   void memberFn();
  6. };
  7.  
  8. A:A()
  9. {
  10.   variable = 3;
  11.   memberFn();
  12. }
  13.  
is valid. Note if you declare something with the same name inside of the member function, this member becomes 'shadowed' and you cannot access it directly. To access it indirectly you would do this:
Expand|Select|Wrap|Line Numbers
  1. void A::memberFn()
  2. {
  3.   int variable = 6;
  4.   printf("member 'variable' = %d\n", this->variable); // displays 3
  5.   printf("auto 'variable' = %d\n", variable); // displays 6
  6.  
  7. }
Given what I just stated, can you now figure out what you have done wrong?


Adrian
May 5 '07 #7
Im not sure...

I have declared all the functions within the class now, so they are all accessible to one another, in the menu system i have for example;

Expand|Select|Wrap|Line Numbers
  1.       case '1':
  2.           Enter(OpAmpObject[database_length], database_length);
  3.         break;
I know that OpAmpObject is not defined in the class, and therefore cannot be accessed even though it is declared in main as type OpAmps, the point that is causing my main problem is what to put as the first name in the brackets above, anything i put in it does not like....

your right, i havent done much c++, and i get thoroughly confused as im also learning vb.net at the same time!!!

Thank you again for your help!
May 5 '07 #8
One last thing,

I have a sort member function that passes data to other functions;

Expand|Select|Wrap|Line Numbers
  1. void OpAmps::Sort(OpAmps* Op, unsigned long length)
  2.  
  3.   switch(UserInput) {
  4.     case '1':
  5.       // sort according to name (in alphabetical order)
  6.         qsort(Op,length,sizeof(OpAmps),&OpAmps::SortName);
  7.       break;
  8.  
  9.     case '2':
  10.       // sort according to slew rate (in increasing slew rate order)
  11.         qsort(Op,length,sizeof(OpAmps),&OpAmps::SortSlewRate);
  12.       break;

The functions it passes to are this;

Expand|Select|Wrap|Line Numbers
  1. int OpAmps::SortName(const void *First, const void* Second)
  2. {  
  3.   return strcmp(((OpAmps *) First)->Name, ((OpAmps *) Second)->Name);
  4. }
  5.  
  6. int OpAmps::SortSlewRate (const void *First, const void* Second)
  7. {  
  8.   return (int) ((OpAmps *) First)->SlewRate - ((OpAmps *) Second)->SlewRate;
  9. }
The problem is that i have the same error for both; error C2664: 'qsort' : cannot convert parameter 4 from 'int (__thiscall OpAmps::* )(const void *,const void *)' to 'int (__cdecl *)(const void *,const void *)
May 5 '07 #9
AdrianH
1,251 Expert 1GB
Im not sure...

I have declared all the functions within the class now, so they are all accessible to one another, in the menu system i have for example;

Expand|Select|Wrap|Line Numbers
  1.       case '1':
  2.           Enter(OpAmpObject[database_length], database_length);
  3.         break;
I know that OpAmpObject is not defined in the class, and therefore cannot be accessed even though it is declared in main as type OpAmps, the point that is causing my main problem is what to put as the first name in the brackets above, anything i put in it does not like....
So you are saying that in your main you have an array of OpAmpDb called OpAmpObject? And that you want to pass (I am assuming) the last element in that array? Somehow I don’t think that is what you are intending, but I’m not sure. Please clarify, but read the following first:

Are you aware you are passing two (possibly different) instances of OpAmpDb to your functions Enter/Save/Load and Sort? When you call a member function that is not static, it implicitly passes the object that you are operating on. I.e.:
Expand|Select|Wrap|Line Numbers
  1. class A
  2. {
  3.   int variable;
  4.   public:
  5.     void foo();
  6. };
  7.  
  8. void A::foo()
  9. {
  10.   variable = 3;
  11. }
  12.  
  13. int main()
  14. {
  15.   A instance;
  16.   instance.foo();
  17. }
Shown in the example in the main function is the creation of an ‘A’ class object named ‘instance’. The next line calls the function foo() on that instance, thus, setting ‘variable’ in that instance to 3. And how does it do that? By passing an implicit pointer to ‘instance’ (known as the ‘this’ pointer).

Does that make sense?

So what I am saying is that those functions I referred to (Enter/Save/Load/Sort) have two instances being passed to them; the implicit one and the explicit one. Is this intentional?

your right, i havent done much c++, and i get thoroughly confused as im also learning vb.net at the same time!!!
Well, good luck. ;)


Adrian
May 5 '07 #10
AdrianH
1,251 Expert 1GB
One last thing,

I have a sort member function that passes data to other functions;

Expand|Select|Wrap|Line Numbers
  1. void OpAmps::Sort(OpAmps* Op, unsigned long length)
  2.  
  3.   switch(UserInput) {
  4.     case '1':
  5.       // sort according to name (in alphabetical order)
  6.         qsort(Op,length,sizeof(OpAmps),&OpAmps::SortName);
  7.       break;
  8.  
  9.     case '2':
  10.       // sort according to slew rate (in increasing slew rate order)
  11.         qsort(Op,length,sizeof(OpAmps),&OpAmps::SortSlewRate);
  12.       break;

The functions it passes to are this;

Expand|Select|Wrap|Line Numbers
  1. int OpAmps::SortName(const void *First, const void* Second)
  2. {  
  3.   return strcmp(((OpAmps *) First)->Name, ((OpAmps *) Second)->Name);
  4. }
  5.  
  6. int OpAmps::SortSlewRate (const void *First, const void* Second)
  7. {  
  8.   return (int) ((OpAmps *) First)->SlewRate - ((OpAmps *) Second)->SlewRate;
  9. }
The problem is that i have the same error for both; error C2664: 'qsort' : cannot convert parameter 4 from 'int (__thiscall OpAmps::* )(const void *,const void *)' to 'int (__cdecl *)(const void *,const void *)
Make the functions static:
Expand|Select|Wrap|Line Numbers
  1. class OpAmpDb
  2. {
  3. public:
  4. // ...
  5.     static int SortName(const void*, const void*);
  6.     static int SortSlewRate(const void*, const void*);
  7. //...
  8. };
Don't use static when defining the function. I.e. this remains the same:
Expand|Select|Wrap|Line Numbers
  1. int OpAmps::SortName(const void *First, const void* Second)
  2. {  
  3.   return strcmp(((OpAmps *) First)->Name, ((OpAmps *) Second)->Name);
  4. }
  5.  
  6. int OpAmps::SortSlewRate (const void *First, const void* Second)
  7. {  
  8.   return (int) ((OpAmps *) First)->SlewRate - ((OpAmps *) Second)->SlewRate;
  9. }
Using static will make the 'this' implict pointer not implicit. I.e. it is not passed.
Expand|Select|Wrap|Line Numbers
  1. class A
  2. {
  3. public:
  4.   int variable;
  5.   static void bar();
  6. }
  7.  
  8. void A::bar()
  9. {
  10.   variable = 3; // invalid since A::bar() is a static function of class A.
  11. }
  12.  

Adrian
May 5 '07 #11

Sign in to post your reply or Sign up for a free account.

Similar topics

1
by: Bob Rock | last post by:
Hello, in the last few days I've made my first few attempts at creating mixed C++ managed-unmanaged assemblies and looking aftwerwards with ILDASM at what is visible in those assemblies from a...
6
by: moi | last post by:
hi, im fairly new to c++ and as part of a module at uni im learning it. i know the basics i suppose, but as our final hand-in we have to alter code we wrote for an earlier assignment to use...
14
by: Pratts | last post by:
I am a new one who have joined u plz try to help me bcoz i could not find ny sutiable answer foer this Question Qus>>why do we need classes when structures provide similar functionality??
6
by: nick | last post by:
I have tried finding an answer to this, but most people just explain classes as a more modular way to program. It seems to me that (forgetting OO programming which I don't quite understand) the...
6
by: Ken Allen | last post by:
OK, I admit that I have been programming since before C++ was invented, and I have developed more than my share of assembly language systems, and even contributed to operating system and compiler...
6
by: David Lozzi | last post by:
Howdy, I'm new to classes. Below is my class User. (is this a reserved namespace or class?) It works great, kind of. If I specify the username and password, the correct firstname and lastname...
7
by: OpticTygre | last post by:
Alright, so I'm messing around with some code, and I brought up a good question to myself. If creating a class called "Person", and filling that class with variables, properties like: Public...
14
by: pmclinn | last post by:
I've noticed that many programmers use classes to store data about such things like: Class Customers .....Phone ....ID ....Address End Class....
5
by: eBob.com | last post by:
I am trying to change some Structures to Classes. The Classes now look like this ... Public Class OneAttr Public AttrName As String Public Column As String Public Caption As String End Class...
2
by: thomasfarrow | last post by:
At work, our development team has a development standards document that insists Structures should never be used. I'm looking to change this standard but need a suitable argument in order to make...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.