2

I am very new to programming, but have been following c++ tutorials and amassing a number of PDFs for the last week or so to help me out. I couldn't find anything in them or online that answered my question clearly enough. Please forgive me for my newbie-ness.

Pertinent code:

Logfile.hpp

// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// HEADER :: CLASS INTERFACE FILE

// ==============================
// Include Guard
#ifndef __LOGFILE_INCLUDED__ // If Actor.hpp hasn't been included yet
#define __LOGFILE_INCLUDED__ // Define this for the compiler so it knows it has now been included

// ==============================
// Forward declared dependencies

// ==============================
// Included dependencies
#include <iostream>
#include <fstream>

// ==============================
// Actual class
class Logfile { // Logfile
public:
    // Globally accessible variables
    bool LACT; // Is log file active?
    std::ofstream LOG; // Actual log file
    std::string entry; // Data to be entered in log file

    // ==============================
    // Core methods
    Logfile(); // Constructor
    ~Logfile(); // Destructor

    // Additional methods
    bool isActive(); // Is log file active?
    void logEntry(std::string entry); // Make an entry in the log if 'LACT' is set to true
    void toggleLog(); // Toggle log file open or closed
};

extern Logfile *log; // This variable is declared in main

#endif // __LOGFILE_INCLUDED__

Logfile.cpp

// ==============================
// Included dependencies
#include "Logfile.hpp"

// ==============================
// Core methods
Logfile::Logfile() { // Constructor
    LACT = true; // Toggle logfile to active
    LOG.open ("LOG.txt"); // Open 'log.txt' and prepare it to receive 'LOG' entries
    LOG << "LOG FILE CLASS CONSTRUCTED\n";
    LOG << "LOG FILE OPENED\n";
}

Logfile::~Logfile() { // Deconstructor
    LOG << "LOG FILE CLOSED\n";
    LOG << "LOG FILE CLASS DECONSTRUCTED";
    LOG.close(); // Close log file
}

// Additional methods
bool Logfile::isActive() { // Is log file active?
    if ( LACT ) return true;
    else return false;
}

void Logfile::logEntry(std::string entry) { // Make an entry in the log if 'LACT' is set to true
    if ( LACT ) LOG << entry << std::endl;
}

void Logfile::toggleLog() { // Toggle log file open or closed
    if ( LACT ) { // Log file is active
        LOG << "LOG FILE CLOSED\n";
        LOG.close(); // Close log file
    } else { // Log file is inactive
        LOG.open ("LOG.txt"); // Open 'log.txt' and prepare it to receive 'LOG' entries
        LOG << "LOG FILE OPENED\n";
    }
}

Engine.hpp

// ==============================
// Forward declared dependencies
class Logfile;

class Engine { // Core system, main loop
public :
    // Globally accessible variables 
    Logfile *log; // Declare 'log' as an empty pointer (*)

Engine.cpp

// ==============================
// Included dependencies
#include "Logfile.hpp"

// ==============================
// Core methods
Engine::Engine() { // Constructor method
    // Initialization
    log = new Logfile(); // Declare 'log' as pointer to access log file
    TCODConsole::initRoot(80,50,"Testbed",false); // Create 'root' console (not fullscreen)
    if ( log->isActive() ) log->logEntry("(TCODConsole) Root console initialized"); // WORKS

Map.hpp

// ==============================
// Forward declared dependencies
class Logfile;

extern Logfile *log; // Pointer exists in Engine.hpp

Map.cpp

// ==============================
// Included dependencies
#include "Logfile.hpp"

if ( log->isActive() ) log->logEntry("(TCODConsole) Root console initialized"); TERMINATION STATUS 3
if ( tiles[(x-1)+y*width].tType =="floor" ) tally++; // Left tile status, add 1 to tally if floor  :  TERMINATION STATUS 3
if ( tiles[(x-1)+(y-1)*width].canWalk ) tally++; // Left-top tile status, add 1 to tally if floor  :  WORKS

If I understand correctly, a termination status 3 indicates that I am referencing a variable incorrectly in regards to whether it's a pointer or not...? I initially ran into the problem when I wanted to access the tType string from an individual tile in the 2Darray in Map.cpp (though I can access the boolean variable canWalk just fine...), and couldn't figure out what was wrong, so I decided to learn to implement an external log to find the problem...but I guess I found my way back to the same issue while doing that...

Any help is greatly appreciated, as is criticism, I have a lot to learn.

--

My initial purpose for asking this question was (now I realize) to get a globally declared object accessible from any *.cpp file in a multi-file program. I just found this answer: http://www.cplusplus.com/forum/beginner/3848/, in case this might be helpful to anyone else with a similar problem.

Jeremy
  • 53
  • 6
  • 4
    Hey Guy, this is a lot of code to read through, usually people try to reduce there code and just show the problem area. Read the FAQ its quite helpful for getting good answers. Otherwise post on http://codereview.stackexchange.com/ – Fantastic Mr Fox Nov 15 '12 at 01:59
  • 2
    This question is not about a compilation error. Consequently it is assumed you can post something that is short, self-contained, **compiles**, and is exemplary of the problem you're having. This definitely misses at least one of those; arguably all of them. Please see [SSCCE](http://sscce.org) and reformulate your question. – WhozCraig Nov 15 '12 at 02:04
  • And the equality comparison between something unknown to us and a string literal, `tiles[(x-1)+y*width].tType =="floor"` should be a big red flag you may want to consider looking at. – WhozCraig Nov 15 '12 at 02:06
  • 1
    `if ( log->isActive() ) log->logEntry("(TCODConsole) Root console initialized"); TERMINATION STATUS 3` <- What does `TERMINATION STATUS 3` do there? How does it even compile without a semicolon before the next `if`? – Daniel Fischer Nov 15 '12 at 02:10
  • @Daniel sorry, there should have been a // in front of the TERMINATION STATUS 3, it was a note for me. -WhozCraig I'll check out the SSCCE link you sent. -Ben Ok, I'll check that out too. Thanks for the responses guys. – Jeremy Nov 15 '12 at 02:44
  • @Jeremy C++ errors/crashes/debugging often only tells you which line an error occurs on. If you put conditions and actions onto the same line, it will often make it harder for you to ascertain where the crash happened. E.g in your example, the crash could be in the log->isActive() or in the log->logEntry() call. (In this case, its unlikely to be isActive) – kfsone Feb 15 '14 at 03:25

1 Answers1

1

In your Logfile.hpp you're missing #include <string>: one of your LogFile classes variables are declared std::string so you need to include that.

In your Engine.cpp you forget to include your Engine.hpp where your LogFile *log; variable is declared. this results in an error in your Engine.cpp file where you try assigning a new LogFile object to it.

So add #include <string> to the top of your Logfile.hpp and add #include "Engine.hpp" to the top of your Engine.cpp

RJFalconer
  • 10,890
  • 5
  • 51
  • 66
ritual_code
  • 147
  • 2
  • 14