Thread: Class as argument

  1. #1
    Registered User
    Join Date
    Mar 2010
    Posts
    90

    Class as argument

    Hello,
    I would like to pass class as argument to/from a function which read/write to file.
    I am a c++ novice and try some ways but no one works for me.

    header:
    Code:
    #include <string>
    
    class MyClass
    {
    public:
    	char     FullName[40];                
    	char     CompleteAddress[120];        
    	char     Gender;                      
    	double Age;                         
    	bool     mybool;    
    };
    
    std::string filename="myJunk.dat";
    int RWrecord (bool RW, long record, MyClass mc);
    function in other file
    Code:
    #include <fstream>
    #include <iostream>
    #include <string.h>
    #include <string>
    #include <io.h>
    using namespace std;
    
    int RWrecord (bool RW, long record, MyClass)
    {
        MyClass mc;
     if (RW) //read or write 
        {
            ifstream ifs(filename.c_str(), ios::binary);
            ifs.seekg (sizeof(mc)*record, ios::beg);
            ifs.read((char*)&mc, sizeof(mc));
            ifs.close();
        }
        else
        {
            ofstream ofs(filename.c_str(), ios::binary);
            ofs.seekp (sizeof(mc)*record, ios::beg);
            ofs.write((char*)&mc, sizeof(mc));
            ofs.close();
        }
        return 0;
    }
    header is included in main file
    from where I call function:
    Code:
    bool RW=false; //read
    long record = 3;
    
    int RWrecord (bool RW, long record, *MyClass)
    //
    // I would like class elements from record 3 here
    but I get much errors during compiling.
    Please help.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    One way is to define a function template with the class type for the template parameter. However, I suggest that you overload operator<< and operator>> for the class instead, so that MyClass objects can be read and written with std::istream and std::ostream.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Mar 2010
    Posts
    90
    Thank you laserlight,
    As a novice I need more concrete help to get this working with situation as presented.
    When I have this code in my main function it works and I can read and write specific record to file.
    But I have trouble when RWrecord is in other file.
    And this is because I plan to use that function from more than one project.

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I will stick with my recommendation of overloading those operators. You should also be wary of the use of those I/O operations that interpret the object as a stream of bits as that can fail to be correct when the class is not a POD type, or has pointer members.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User Swarvy's Avatar
    Join Date
    Apr 2008
    Location
    United Kingdom
    Posts
    195
    You could include a forward declaration of the class in your cpp file. That should work but laserlight's idea is better although slightly more technical to implement.

  6. #6
    Registered User
    Join Date
    Mar 2010
    Posts
    90
    Anyway, I still dont move forward with my example.
    It seems I have more errors here.

    In header bClass.h I have line:
    Code:
    std::string filename="myJunk.dat";
    This header is included in my main file (main.cpp) and in my file with functions (bClass.cpp),
    and compiler says:

    Compiling: bClass.cpp
    Compiling: Main.cpp
    Linking console executable: bin\Release\aass.exe
    obj\Release\Main.o:Main.cpp.bss+0x0): multiple definition of `filename'
    obj\Release\bClass.o:bClass.cpp.bss+0x0): first defined here
    collect2: ld returned 1 exit status
    Process terminated with status 1 (0 minutes, 10 seconds)
    0 errors, 0 warnings

    How is this possible and what to do to fix this?

  7. #7
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    The header file is being included for every #include "yourheader.h" you make.

    This leads to multiple definitions of various things as a matter of course.

    The way to stop this is to use the preprocessor to make something called an "include guard", which is just a conditional #define (based on whether it is defined or not). C++ does not emulate smarter modules in other languages. That is why you must do this.

  8. #8
    Registered User
    Join Date
    Mar 2010
    Posts
    90
    I see.
    Now I do this (I look to some example):

    At top of header bClass.h I added:
    Code:
    #ifndef BCLASS_H
    #define BCLASS_H
    and at the end

    Code:
    #endif //BCLASS_H
    But same happens.
    Sure, filename is not defined nowhere else.

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Do not use a global variable. If you really do want it, you could declare it as extern in the header and define it in exactly one source file, but from what I see it is unnecessary here, and so should be avoided.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Have you tried looking at where the compiler encountered it before? It did say it was encountered previously "here".
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  11. #11
    Registered User
    Join Date
    Mar 2010
    Posts
    90
    Hello Elysia,
    No, I cannot locate where.
    This is "build log" which dont offer any debug possibility, just text.
    Interesting is that in build messages, which can show where is error I got this

    ||=== Build finished: 0 errors, 0 warnings ===|

    But this is not correct,
    because when I run a program they want to build again and again.
    I use CodeBlocks IDE and here is possible such errors because CB is still under developing.
    But I need CB because of usability in Windows and Linux.

    Is here any possibility to attach a project?

  12. #12
    Registered User
    Join Date
    Mar 2010
    Posts
    90
    I finally get solution which compiles well
    header:

    Code:
    #ifndef BCLASS_H
    #define BCLASS_H
    
    class MyClass
    {
    public:
    	char   FullName[40];    
    	char   CompleteAddress[120];       
    	char   Gender;                 
    	double Age;                        
    	bool   myBool;    
    };
    
    int RWrecord (bool RW, long record, MyClass *mc);
    #endif //BCLASS_H
    function file:

    Code:
    int RWrecord (bool RW, long record, MyClass *mc)
    {
     std::string filename="myJunk.dat";
     if (RW)
        {
            std::ifstream ifs(filename.c_str(), std::ios::binary);
            ifs.seekg (sizeof(mc)*record, std::ios::beg);
            ifs.read((char*)&mc, sizeof(mc));
            ifs.close();
        }
        else
        {
            std::ofstream ofs(filename.c_str(), std::ios::binary);
            ofs.seekp (sizeof(mc)*record, std::ios::beg);
            ofs.write((char*)&mc, sizeof(mc));
            ofs.close();
        }
        return 0;
    }
    main:

    Code:
    int main()
    {
    	std::string filename="myJunk.dat";
    	remove(filename.c_str());
    
        bool RW;
        long record;
    	MyClass one;
    
    	strcpy(one.FullName, "Row two");
    	strcpy(one.CompleteAddress, "My row two adress");
    	one.Gender = 'M';
    	one.Age = 3.14;
    	one.myBool = true;
    
        record = 2;
        RW = true;
        int RWrecord (bool RW, long record, MyClass *one);
    
    //-------------------------------------------------------------------
    
        record = 2;
        RW = false;
        MyClass two;
    
        int RWrecord (bool RW, long record, MyClass *two);
    
    	std::cout << "My Information\n";
    	std::cout << "My Name: " << two.FullName << std::endl;
    	std::cout << "Address:      " << two.CompleteAddress << std::endl;
    
    	if(two.Gender == 'f' || two.Gender == 'F')
    		std::cout << "Gender:       Female" << std::endl;
    	else if(two.Gender == 'm' || two.Gender == 'M')
    		std::cout << "Gender:       Male" << std::endl;
    	else
        std::cout << "Gender:       Unknown" << std::endl;
    
        std::cout << "Age:          " << two.Age << std::endl;
    	return 0;
    }
    1 delete file if exist
    2 fill data values to copy of class "one"
    3 set RW to write and record to 2
    4 call RWrecord to write data to record 2 (171 byte from beggining of file)
    5 call RWrecord to read data from record 2 to new variable "two"
    6 print data from variable two to console

    Program compiles well
    but my data dont passes correct
    I assume that problem lies in my general missunderstanding of strings and pointers.
    So please if someone could correct my code to get it to working condition.
    Thanks.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Whats the best way to control a global class?
    By parad0x13 in forum C++ Programming
    Replies: 3
    Last Post: 11-12-2009, 05:17 PM
  2. Default class template problem
    By Elysia in forum C++ Programming
    Replies: 5
    Last Post: 07-11-2008, 08:44 AM
  3. Creating a database
    By Shamino in forum Game Programming
    Replies: 19
    Last Post: 06-10-2007, 01:09 PM
  4. Replies: 7
    Last Post: 05-26-2005, 10:48 AM