Structure requires Constructor

This is a discussion on Structure requires Constructor within the C++ Programming forums, part of the General Programming Boards category; I get a warning about initializing the Zone structure's two components (Zone::ZoneCoords & Zone::ZoneMap), then an error stating "synthesized method ...

  1. #1
    C++ Enthusiast M.Richard Tober's Avatar
    Join Date
    May 2011
    Location
    Georgia
    Posts
    56

    Question Structure requires Constructor

    I get a warning about initializing the Zone structure's two components (Zone::ZoneCoords & Zone::ZoneMap), then an error stating "synthesized method 'Zone::Zone()' first required in World's initializer list.

    Code:
    #ifndef WORLD_H
    #define WORLD_H
    
    #include <vector>
    #include "constants.h"
    
    struct Coords
    {
        int x;
        int y;
    };
    typedef std::vector<Coords> ZoneLookupTable;
    
    struct Tile
    {
        int ID;
        int Type;
    };
    typedef std::vector<Tile> RowVec;
    typedef std::vector<RowVec> ZoneVec;
    
    struct Zone
    {
        // Why does the compile require this constructor?
        //Zone() : ZoneCoords(), ZoneMap() {}
        Coords ZoneCoords;
        ZoneVec ZoneMap;
    };
    typedef std::vector<Zone> Area;
    
    class World
    {
        public:
            World() : AreaID(1), CurrentZone(), CurrentArea(), ZoneTable(), VecZoneFileNames() {};
            void Load(int ID = 1);
            void Update(float x, float y);
            void Save();
    
            // Helpers
            void CreateZone(float x, float y);
            std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems);
            std::string GenerateZoneFilePath(float x, float y);
            void LoadZones();
    
            // Accessors
            int GetID() { return AreaID; }
            Zone &GetZone() { return CurrentZone; }
            Area &GetArea() { return CurrentArea; }
            ZoneLookupTable &GetZLT() { return ZoneTable; }
    
        private:
            int AreaID;
            Zone CurrentZone;
            Area CurrentArea;
            ZoneLookupTable ZoneTable;
            std::vector<std::string> VecZoneFileNames;
    };
    
    #endif // WORLD_H
    Why does the Zone struct seem to require a constructor be defined?
    I know it's because it contains other structures, but I don't know why. Wouldn't an implicity created default constructor work when I leave out my manually constructed one? I searched for answers with keywords structure and constructor, then relized I wouldn't know the answer if I saw it. Thank you for any time gurus, you make my day.

    As always, go easy on me, and thanks in advance!
    Eventually, I decided that thinking was not getting me very far and it was time to try building.
    — Rob Pike, "The Text Editor sam"

  2. #2
    Registered User
    Join Date
    Jun 2005
    Posts
    6,252
    From what you have shown it is not possible to tell.

    Your code is #include'ing constants.h (which we can't see) and needs to #include <string> in order to compile.

    The elements of vectors need to have a constructor that accepts no arguments and, in some circumstances, the compiler is prevented from generating them. Such a thing would explain your problem .... except that your code, as shown, does not exhibit such concerns.
    Right 98% of the time, and don't care about the other 3%.

  3. #3
    C++ Enthusiast M.Richard Tober's Avatar
    Join Date
    May 2011
    Location
    Georgia
    Posts
    56
    Wow... It should need <string>, but was compiling without it... well - here is the constants.h for acedemic practices.
    Note: Code::Blocks has been flaking out on me a lot lately. Not usually things like this though... how the heck was it compiling. I'm always split between the nitty-gritty world of vim and hand-made makefiles, and the conversely shiny allure of neat IDE's Additional notes: The World class was pulled out of another project to work on independently. The implementation file includes <string>. I'll include the implementation file also for academic potential. Don't laugh.

    constants.h
    Code:
    #ifndef CONSTANTS_H_INCLUDED
    #define CONSTANTS_H_INCLUDED
    
    const bool MUSIC = false;
    const bool DEBUG = false;
    const bool SHOWFPS = true;
    
    // Global System Constants
    const int SCREEN_WIDTH  = 1024;
    const int SCREEN_HEIGHT = 768;
    const int SCREEN_BPP    = 32;
    const char GAME_TITLE[] = "Sellsword";
    
    // Global Game Constants
    const int TILE_WIDTH = 32;
    const int TILE_HEIGHT = 32;
    const int TILE_COLS_X_W = SCREEN_WIDTH / TILE_WIDTH;
    const int TILE_ROWS_Y_H = SCREEN_HEIGHT / TILE_HEIGHT;
    const int TILE_SHEET_COLS = 16;
    const int TILE_SHEET_ROWS = 12;
    const double CHARACTER_SPEED = 200.0;
    
    // Enumerations
    enum {SOUTH, WEST, EAST, NORTH};
    enum {RIGHT_FOOT, MIDDLE_FOOT, LEFT_FOOT};
    enum {MENU_CHOICE_NEW, MENU_CHOICE_LOAD, MENU_CHOICE_QUIT};
    
    // GameState
    enum {INITIALIZING, OPENING, MENU, PLAYING, LOADING, QUITTING, OPTIONS};
    
    // GameStatePlay
    enum {WALKING, SAILING, FLYING, PAUSE, RESTING, COMBAT, TALKING, QSAVE,  QLOAD, OPTS, CUTSCENE, QUIT, EDITMODE, HELPMODE, SCRNSHOT};
    
    #endif // CONSTANTS_H_INCLUDED
    world.cpp
    Code:
    #include <iostream>
    #include <string>
    #include <sstream>
    #include <fstream>
    #include <dirent.h>
    #include <cstring>
    #include <cstdlib>
    #include <vector>
    #include "world.h"
    
    using namespace std;
    
    void World::Load(int ID)
    {
        // Read all valid zone (*.zon) files in the maps directory.
        // Load the zones ending in the AreaID we want.
        // This function uses a logic waterfall to sanity check
        // the file names against a number of criteria.
        AreaID = ID;
    
        // Read the Zones from disk.
        LoadZones();
    
        // Check that 9 usable zones were loaded, lest we create them.
        if (VecZoneFileNames.size() < 9)
        {
            VecZoneFileNames.clear(); // Clear potential damaged or partial zones.
            int w = SCREEN_WIDTH;
            int h = SCREEN_HEIGHT;
            int cx = w/2;
            int cy = h/2;
            CreateZone(cx, cy);     // Center
            CreateZone(cx,   cy-h); // North
            CreateZone(cx+w, cy-h); // Northeast
            CreateZone(cx+w,   cy); // East
            CreateZone(cx+w, cy+h); // Southeast
            CreateZone(cx,   cy+h); // South
            CreateZone(cx-w, cy+h); // Southwest
            CreateZone(cx-w,   cy); // West
            CreateZone(cx-w, cy-h); // Northwest
    
            // Read the Zones from disk.
            LoadZones();
            if (VecZoneFileNames.size() < 9) throw("World::Load: Zone Read error.");
    
        }
    }
    
    void Update(float x, float y)
    //void World::Update(const std::string &ZFP, std::vector<sf::Sprite> &vTS)
    {
    //    ifstream ZoneFile(ZFP.c_str());
    //    string input;
    //    stringstream ss;
    //    vector<string> vInput;
    //    ZoneMap.clear();
    //    while(getline(ZoneFile, input))
    //    {
    //        // Skip comments
    //        if (input[0] != '#')
    //        {
    //            vInput.clear();
    //            // Read in and tokenize line
    //            split(input, ':', vInput);
    //            // convert to ints
    //            //cout << "Debug: vInput size: " << vInput.size() << endl;
    //            unsigned int i = 0;
    //            while (i < vInput.size())
    //            {
    //                int x = atoi(vInput[i].c_str());
    //                int y = atoi(vInput[i+1].c_str());
    //                int tileID = atoi(vInput[i+2].c_str());
    //                i += 3;
    //
    //                Tile NewTile(vTS[tileID], x, y);
    //                //if (DEBUG) cout << "World Loader Data Sample: NewTile.GetPos().y: " << NewTile.GetPos().y << endl;
    //                // push Tiles into [RowMap]
    //                RowMap.push_back(NewTile);
    //            }
    //            ZoneMap.push_back(RowMap);
    //        }
    //    }
    //    ZoneFile.close();
    }
    
    void World::Save()
    {
    //    //Check the ZoneLookUp table
    //    // Save the 8 areas there
    //
    //    CurrentArea
    //    string ZFP = GenerateZonePath(InteriorPoint);
    //
    //    MapVectorZone TZM;
    //    //TZM = LocateZoneMap(TargetZonePath);
    //    TZM = GetZone();  // Place holder
    //
    //    float Time = WorldClock.GetElapsedTime();
    //    cout << "Saving: " << ZFP << endl;
    //    ofstream outfile(ZFP.c_str());
    //
    //    if (!outfile) throw("World::SaveZone: Couldn't open zone file for saving!");
    //    outfile << "# Area Label \"" << string(ZFP).substr(5, 11) << "\"." << endl;
    //    outfile << "# System generated zone file: " << ZFP << endl;
    //    outfile << "# Version 1.2" << endl;
    //
    //    for (int y = 0; y < TILE_ROWS_Y_H; ++y)
    //    {
    //        for(int x = 0; x < TILE_COLS_X_W; ++x)
    //        {
    //            int t = TZM.at(y).at(x).GetID();
    //            outfile << (y < 100 ? "0" : "") << (y < 10 ? "0" : "") << y << ":"
    //                    << (x < 100 ? "0" : "") << (x < 10 ? "0" : "") << x << ":"
    //                    << (t < 100 ? "0" : "") << (t < 10 ? "0" : "") << t;
    //            if (x < TILE_COLS_X_W - 1) outfile << ": ";
    //        }
    //        outfile << endl;
    //        cout << "[]"; // Update status indicator
    //    }
    //
    //    outfile.close();
    //    cout << " Complete!" << endl;
    //    cout << ZFP << " saved in " << (WorldClock.GetElapsedTime() - Time) << " secs."<< endl;
    //
    }
    
    void World::CreateZone(float x, float y)
    {
        string ZoneFileName = GenerateZoneFilePath(x, y);
        /*DEBUG*/cout << "Creating: " << ZoneFileName;
    
        ofstream outfile;
        outfile.open(ZoneFileName.c_str());
        if (!outfile) throw("World::CreatZone: Couldn't open zone file for creation!");
    
        outfile << "# Area Label \"" << string(ZoneFileName).substr(5, 11) << "\"." << endl;
        outfile << "# System generated zone file: " << ZoneFileName << endl;
        outfile << "# Version 1.4" << endl;
    
        // Text Files must be written left to right
        for (int y = 0; y < TILE_ROWS_Y_H; ++y)
        {
            for(int x = 0; x < TILE_COLS_X_W; ++x)
            {
                // Write the ID for tile (1,0) and Walkable Type (000)
                outfile << "001" << ":" << "000";
                if (x < TILE_COLS_X_W - 1) outfile << ": ";
            }
            outfile << endl;
        }
        outfile.close();
        cout << " Complete!" << endl;
    }
    
    // Helper for Loader
    std::string World::GenerateZoneFilePath(float x, float y)
    {
        char  SignX = x > -1 ? 'P' : 'N';
        char  SignY = y > -1 ? 'P' : 'N';
        int coord_x = abs(static_cast<int>(x) / SCREEN_WIDTH);
        int coord_y = abs(static_cast<int>(y) / SCREEN_HEIGHT);
    
        stringstream ZoneName;
    
        ZoneName << "maps/";
        ZoneName << SignX << (coord_x < 100 ? "0" : "") << (coord_x < 10 ? "0" : "") << coord_x;
        ZoneName << SignY << (coord_y < 100 ? "0" : "") << (coord_y < 10 ? "0" : "") << coord_y;
        ZoneName << "A"   << (AreaID  < 100 ? "0" : "") << (AreaID < 10 ? "0" : "") << AreaID << ".zon";
    
        /*DEBUG*/ cout << "World::GenerateZoneFilePath(" << x << "," << y << "):" << endl;
        cout << "\"" << ZoneName.str() << "\"" << endl;
        return ZoneName.str();
    }
    
    std::vector<std::string> &World::split(const std::string &s, char delim, std::vector<std::string> &elems)
    {
        std::stringstream ss(s);
        std::string item;
        while(std::getline(ss, item, delim)) {
            elems.push_back(item);
        }
        return elems;
    }
    
    void World::LoadZones()
    {
        DIR *DirPtr;
        struct dirent *DirEntry;
    
        if((DirPtr = opendir("maps")))
        {
            while ((DirEntry = readdir(DirPtr)))
            {
                string CurrFile(DirEntry->d_name);
                if(CurrFile.length() == 16)
                    if(CurrFile[8] == 'A')
                        if(atoi(string(CurrFile.substr(9, 3)).c_str()) == AreaID)
                            if(CurrFile[0] == 'P' || CurrFile[0] == 'N')
                                if(CurrFile[4] == 'P' || CurrFile[4] == 'N')
                                    if(CurrFile.compare(12, 4, ".zon") == 0)
                                        VecZoneFileNames.push_back(CurrFile.substr(0, 12));
            }
            closedir(DirPtr);
        }
        else throw("[World::Load]: No maps directory found. (ex: ./maps/N000P000A001.zon)");
    }
    Eventually, I decided that thinking was not getting me very far and it was time to try building.
    — Rob Pike, "The Text Editor sam"

  4. #4
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Is it a warning or an error? What is the compiler (Code::Blocks is not a compiler) and the flags?
    Your code should not produce an error and I don't see any reason to warn about synthesized default constructor either.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  5. #5
    C++ Enthusiast M.Richard Tober's Avatar
    Join Date
    May 2011
    Location
    Georgia
    Posts
    56
    Quote Originally Posted by anon View Post
    Is it a warning or an error? What is the compiler (Code::Blocks is not a compiler) and the flags?
    Your code should not produce an error and I don't see any reason to warn about synthesized default constructor either.
    My Errors without the constructor:
    Code:
    ||=== Test, Debug ===|
    include/world.h||In constructor ‘Zone::Zone()’:|
    include/world.h|24|warning: ‘Zone::ZoneCoords’ should be initialized in the member initialization list|
    include/world.h|24|warning: ‘Zone::ZoneMap’ should be initialized in the member initialization list|
    include/world.h||In constructor ‘World::World()’:|
    include/world.h|34|note: synthesized method ‘Zone::Zone()’ first required here |
    include/world.h||In constructor ‘Zone::Zone()’:|
    include/world.h|24|warning: ‘Zone::ZoneCoords’ should be initialized in the member initialization list|
    include/world.h|24|warning: ‘Zone::ZoneMap’ should be initialized in the member initialization list|
    include/world.h||In constructor ‘World::World()’:|
    include/world.h|34|note: synthesized method ‘Zone::Zone()’ first required here |
    ||=== Build finished: 2 errors, 4 warnings ===|
    gcc 4.5.2!
    I know, I know. That's why I was like, "huh?"

    Code:
    Using built-in specs.
    COLLECT_GCC=gcc
    COLLECT_LTO_WRAPPER=/usr/lib/x86_64-linux-gnu/gcc/x86_64-linux-gnu/4.5.2/lto-wrapper
    Target: x86_64-linux-gnu
    Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.5.2-8ubuntu4' --with-bugurl=file:///usr/share/doc/gcc-4.5/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.5 --enable-shared --enable-multiarch --with-multiarch-defaults=x86_64-linux-gnu --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib/x86_64-linux-gnu --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.5 --libdir=/usr/lib/x86_64-linux-gnu --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-plugin --enable-gold --enable-ld=default --with-plugin-ld=ld.gold --enable-objc-gc --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
    Thread model: posix
    gcc version 4.5.2 (Ubuntu/Linaro 4.5.2-8ubuntu4)
    Last edited by M.Richard Tober; 01-24-2012 at 05:15 AM.
    Eventually, I decided that thinking was not getting me very far and it was time to try building.
    — Rob Pike, "The Text Editor sam"

  6. #6
    C++ Enthusiast M.Richard Tober's Avatar
    Join Date
    May 2011
    Location
    Georgia
    Posts
    56
    I solved it more or less. I restructured and rethought the taxonomy for my classes. This in turn seemed to alleviate some sort of circular name clash. Wish I knew more, but at least it's cleaned up.

    world.h
    Code:
    #ifndef WORLD_H
    #define WORLD_H
    
    #include <vector>
    #include <string>
    #include "constants.h"
    
    struct Coords
    {
        int x;
        int y;
    };
    
    struct Tile
    {
        int ID;
        int Type;
    };
    
    typedef std::vector<std::string> VecString;
    typedef std::vector<Tile> Row;
    typedef std::vector<Row> Zone;
    typedef std::vector<Zone> Area;
    
    struct ZoneHeader
    {
        Coords ZoneCoords;
        Zone ZoneMap;
    };
    
    class World
    {
        public:
            World() : AreaID(1), LocalArea(9), TotalArea(100), VecZoneFileNames(9) {};
    
            void Load(int ID = 1);
            void Update(float x, float y);
            void Save();
    
            // Helpers
            void LoadZones();
            void CreateZone(float x, float y);
            std::string GenerateZoneFilePath(float x, float y);
            std::vector<std::string> &split(const std::string &s,
                std::vector<std::string> &elems, char delim = ' ');
    
            // Accessors
            ///int GetID() { return AreaID; }
            Area &GetArea() { return TotalArea; }
            Area &GetLocalArea() { return LocalArea; }
    
        private:
            int AreaID;
            Area LocalArea;
            Area TotalArea;
            VecString VecZoneFileNames;
    };
    
    #endif // WORLD_H
    Eventually, I decided that thinking was not getting me very far and it was time to try building.
    — Rob Pike, "The Text Editor sam"

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How do I know which function requires a '-lsomething'?
    By hkuser2001 in forum C Programming
    Replies: 1
    Last Post: 05-09-2006, 05:39 AM
  2. PC Game project requires c++ programmers
    By drallstars in forum Projects and Job Recruitment
    Replies: 2
    Last Post: 02-21-2006, 11:23 PM
  3. Replies: 9
    Last Post: 10-26-2005, 07:29 AM
  4. Programs requires portforwarding
    By Da-Nuka in forum Networking/Device Communication
    Replies: 6
    Last Post: 08-28-2005, 12:45 PM
  5. C Moron requires Mucho helpo!
    By tom0987654321 in forum C Programming
    Replies: 5
    Last Post: 04-30-2002, 01:41 PM

Tags for this Thread


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21