Thread: struct with multiple objects in header file issues

  1. #1
    Registered User
    Join Date
    Aug 2011
    Posts
    36

    struct with multiple objects in header file issues

    Problem: I can't get this seemingly simple program to compile. I've tried searching for hours. It's a struct in a .h file along with a function prototype and its src file that uses the function to put values to the struct's objects. I'm using the Code::Blocks v10.05 compiler.

    Compiler errors:
    -------------------------
    E:\My own programs\structure test\struct practice\fruit_struct.h|12|error: variable or field 'apple_f' declared void|
    E:\My own programs\structure test\struct practice\fruit_struct.h|12|error: expected primary-expression before ')' token|
    ||=== Build finished: 2 errors, 0 warnings ===|

    fruit_struct.h file
    Code:
    #ifndef GUARD_fruit_struct_h
    #define GUARD_fruit_struct_h
    
    // fruit_struct.h
    
    #include <string>
    
    struct fruit {
        std::string name;
        int weight;
        float price;
    } apple, banana, melon;
    
    void apple_f(apple&);
    
    #endif
    fruit_struct.cpp
    Code:
    // fruit_struct.cpp
    
    #include <string>
    #include "fruit_struct.h"
    
    void apple_f(apple& apple)
    {
        apple.name = "Apple";
        apple.weight = 2;
        apple.price = 2.0;
    }
    main.cpp
    Code:
    // main.cpp
    
    #include <iostream>
    #include <string>
    #include "fruit_struct.h"
    
    using namespace std;
    
    int main()
    {
        cout << apple.name;
    
        return 0;
    }
    I know I could put this all in one source file and be done, but it's not what I'm trying to accomplish doing this exercise.

    Any help will be appreciated and noted!

  2. #2
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    You defined the fruit struct and made the objects apple, banana and melon. Then you make an apple_f function that accepts an argument of type apple&, forgetting that apple isn't a type!

  3. #3
    Registered User
    Join Date
    Aug 2011
    Posts
    36
    OK, so I changed apple& to fruit&, and I got multiple definition errors having to do with apple, banana, or melon. After that I just got rid of the objects all together. Now it's giving me a "expected primary-expression before '.' error (yes I changed apple.name to fruit.name) in my main.cpp. If it's not one problem, it's the next. I'm thinking it has to do with scoping somehow, but I'm not sure how to alleviate it. However, changing my code around like that is not what I want to do. I want to know if there's a way to make the program that I wrote above to work as intended. I am really stuck, and I can't seem to find any information on how to alleviate this problem.

  4. #4
    Registered User rogster001's Avatar
    Join Date
    Aug 2006
    Location
    Liverpool UK
    Posts
    1,472
    If it's not one problem, it's the next
    haha, too true eh, post your new code
    Last edited by rogster001; 02-25-2012 at 05:28 AM.
    Thought for the day:
    "Are you sure your sanity chip is fully screwed in sir?" (Kryten)
    FLTK: "The most fun you can have with your clothes on."

    Stroustrup:
    "If I had thought of it and had some marketing sense every computer and just about any gadget would have had a little 'C++ Inside' sticker on it'"

  5. #5
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by Darkroman View Post
    OK, so I changed apple& to fruit&, and I got multiple definition errors having to do with apple, banana, or melon. After that I just got rid of the objects all together. Now it's giving me a "expected primary-expression before '.' error (yes I changed apple.name to fruit.name) in my main.cpp. If it's not one problem, it's the next. I'm thinking it has to do with scoping somehow, but I'm not sure how to alleviate it. However, changing my code around like that is not what I want to do. I want to know if there's a way to make the program that I wrote above to work as intended. I am really stuck, and I can't seem to find any information on how to alleviate this problem.
    Multiple definitions will occur if more than one source file includes your header.

    Move the definitions of apple, banana, and melon out of the header file, and place them in exactly ONE .source file.

    To illustrate, in the header.
    Code:
    #ifndef GUARD_fruit_struct_h
    #define GUARD_fruit_struct_h
    
    // fruit_struct.h
    
    #include <string>
    
    struct fruit {
        std::string name;
        int weight;
        float price;
    };                          //  note the instances aren't being defined here
    
    void apple_f(fruit &);
    
    #endif
    and, in one and only one of the source (for example, .cpp) files, define them....
    Code:
    #include "fruit_struct.h"
    
    //    the definitions
    
    fruit apple, banana, melon;
    This assumes apple, banana, and melon only need to be used in one source file. If you need them in more than one source, add this line to the header (and still use ONE source file as above).
    Code:
    extern fruit apple, banana, melon;
    This line is a declaration, not a definition. The extern keyword specifies that apple, banana, and melon are defined somewhere else, as above.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Darkroman View Post
    OK, so I changed apple& to fruit&, and I got multiple definition errors having to do with apple, banana, or melon. After that I just got rid of the objects all together. Now it's giving me a "expected primary-expression before '.' error (yes I changed apple.name to fruit.name) in my main.cpp. If it's not one problem, it's the next. I'm thinking it has to do with scoping somehow, but I'm not sure how to alleviate it. However, changing my code around like that is not what I want to do. I want to know if there's a way to make the program that I wrote above to work as intended. I am really stuck, and I can't seem to find any information on how to alleviate this problem.
    My magic hat is guessing that you tried to access a variable in a class without first creating an instance of the class and accessing that class's instance of the variable.
    You can't directly access variables inside a class since a class is a blueprint!
    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.

  7. #7
    Registered User
    Join Date
    Aug 2011
    Posts
    36
    Thank you, guys! I got my program to work from following your suggestions + my own trial and error. I have one last question, and it pertains to correct use or not. So, I made an extra object for my structure called "contents" so I could call that to display whatever contents i set in my function files. Is this correct usage? Is there a better or more elegant way to do this? I'll put my new working source code.

    fruit_struct.h
    Code:
    #ifndef GUARD_fruit_struct_h
    #define GUARD_fruit_struct_h
    
    // fruit_struct.h
    
    #include <string>
    
    struct fruit {
        std::string name;
        int weight;
        float price;
    };
    
    extern fruit contents, apple, banana, melon;
    
    void fruit_f(fruit &);
    void fruit_out(fruit &);
    
    #endif
    fruit_struct.cpp
    Code:
    // fruit_struct.cpp
    
    #include <iostream>
    #include <string>
    #include "fruit_struct.h"
    
    using std::cout; using std::endl;
    
    fruit contents, apple, banana, melon;
    
    void fruit_f(fruit &f)
    {
        apple.name = "Apple";
        apple.weight = 2;
        apple.price = 2.00;
    
        banana.name = "Banana";
        banana.weight = 1;
        banana.price = 1.00;
    
        melon.name = "Melon";
        melon.weight = 5;
        melon.price = 3.00;
    
        banana.name = "Banana";
    }
    
    void fruit_out(fruit &f)
    {
        cout << "Fruit name: " << apple.name << endl;
        cout << "Weight: " << apple.weight << "lbs" << endl;
        cout << "$" << apple.price << endl << endl;
    
        cout << "Fruit name: " << banana.name << endl;
        cout << "Weight: " << banana.weight << "lbs" << endl;
        cout << "$" << banana.price << endl << endl;
    
        cout << "Fruit name: " << melon.name << endl;
        cout << "Weight: " << melon.weight << "lbs" << endl;
        cout << "$" << melon.price << endl << endl;
    }
    main.cpp
    Code:
    // main.cpp
    
    #include "fruit_struct.h"
    
    int main()
    {
        fruit_f(contents);
        fruit_out(contents);
    
        return 0;
    }

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I don't think you grasp the whole point of objects here.
    An instance is something that has been created from a blueprint.

    So, say you have a Car model (basically a blueprint for making a car; which in our case, is a class). From this blueprint, you can manufacture cars (creating instances of the class).
    It doesn't make sense to start the engine in a blueprint, does it? That is exactly what it means that try to access a class's members directly.
    It does make sense to first create a car, and then manipulate it.

    But your functions fruit_f and fruit_out takes a "dummy" fruit which it does nothing with. Then what's the point of that fruit? Your functions only operate on your "global" fruits.
    You really should make those fruits non-global, btw.
    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.

  9. #9
    Registered User
    Join Date
    Aug 2011
    Posts
    36
    Yeah, it's true I don't know much about constructors, or instances all that much yet. I just got done doing chapter 4 in accelerated c++. It introduced structures but didn't explain it all very well. Basically, my thought process was to make a structure of a generic thing (fruit), have the structure have objects which belong in its category (apple, banana, melon), and hard code the values of each object. Once I get into making classes I'll understand more uses for them.

  10. #10
    Registered User rogster001's Avatar
    Join Date
    Aug 2006
    Location
    Liverpool UK
    Posts
    1,472
    I made an extra object for my structure called "contents"
    That would not really be an 'object' or instance of a fruit though would it, it would be more like a property, a common attribute that 'all' fruits' have in common.

    So you would be talking more about a 'Base Class' to define fundamental things that all fruits share, and work it from there, I mean just for visualisation purposes, not just code.

    Think about a base class 'Vehicle' forget code, just write a tree in pen and paper with 'Vehicle' at the top, try and add some raw fundamentals that that would have :
    'passenger capacity'
    'load capacity'
    'fuel' ....or energy source even??
    'max speed'

    You can add more am sure, it is quite a good mental game thinking it through. You might assume oh wheels, well no because of boats and snowmobiles say!

    so that is where subclasses come in further down the chain, and these will produce the specialisations and branching, air vehicles, to planes, helicopters, hot air balloons.
    class planes (or wingedFlightVehicle)will have things that hot air balloons dont, yet they share common attributes of 'air vehicles' which going back to the root inherit common attributes of 'vehicles'
    Last edited by rogster001; 02-28-2012 at 03:06 PM.
    Thought for the day:
    "Are you sure your sanity chip is fully screwed in sir?" (Kryten)
    FLTK: "The most fun you can have with your clothes on."

    Stroustrup:
    "If I had thought of it and had some marketing sense every computer and just about any gadget would have had a little 'C++ Inside' sticker on it'"

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Header /file module issues
    By rogster001 in forum C++ Programming
    Replies: 7
    Last Post: 10-21-2009, 06:48 AM
  2. Defining multiple classes in the same header file
    By Stonehambey in forum C++ Programming
    Replies: 2
    Last Post: 08-14-2008, 10:36 AM
  3. Header file multiple inclusion question
    By Loctan in forum C++ Programming
    Replies: 16
    Last Post: 05-04-2008, 08:25 PM
  4. Header file (multiple inclusions)
    By cjschw in forum C++ Programming
    Replies: 1
    Last Post: 08-10-2004, 10:28 AM
  5. multiple (ctime) struct tm* objects
    By cjschw in forum C++ Programming
    Replies: 3
    Last Post: 10-08-2003, 01:25 PM