Debug class

Whether you're a newbie or an experienced programmer, any questions, help, or just talk of any language will be welcomed here.

Moderator: Coders of Rage

Post Reply
User avatar
short
ES Beta Backer
ES Beta Backer
Posts: 548
Joined: Thu Apr 30, 2009 2:22 am
Current Project: c++, c
Favorite Gaming Platforms: SNES, PS2, SNES, SNES, PC NES
Programming Language of Choice: c, c++
Location: Oregon, US

Debug class

Post by short »

edit: thanks to xeno for pointing out the vsnprintf function to me, and X abstract X for pointing out the =operator and copy constructor to me.

Code: Select all

/*
 *  Debug.h
 *  XCODE SFML_ENGINE
 *
 *  Created by Benjamin Adamson on 5/31/10.
 *  Copyright 2010 Oregon State University. All rights reserved.
 *
 */

#define dbg Debug::get_Instance()

#include <string>
#include <fstream>
#include <assert.h>
#include <stdio.h>

#ifndef _DEBUG_H_
#define _DEBUG_H_
class Debug
{
private:
	Debug(const Debug& d);	 // copy constructor needs to be private as well.
	Debug();
	~Debug();
	
	// member variables
	const static unsigned int m_sizebuffer = 1028;
	std::ofstream m_file;
	bool m_fileopened;
	char m_buffer[m_sizebuffer];
	va_list m_vl;
	
	//=operator needs to be private
	Debug& operator=(const Debug &rhs)
	{
	}
	
public:
	
	static inline Debug &get_Instance()
	{
		static Debug instance;
		return instance;
	}
	void open_file(const std::string& filename);
	void print(const std::string& fmt, ...);
};

#endif // End include guard.

Code: Select all

/*
 *  Debug.cpp
 *  XCODE SFML_ENGINE
 *
 *  Created by Benjamin Adamson on 5/31/10.
 *  Copyright 2010 Oregon State University. All rights reserved.
 *
 */

#ifndef _DEBUG_H_
#include "Debug.h"
#endif
Debug::Debug()
{
}

Debug::~Debug()
{
	if(m_fileopened)
	{
		m_file.close();
	}
	
}

void Debug::open_file(const std::string& filename)
{
	// file cannot already be opened.
	assert(!m_fileopened);
	
	m_file.clear(); // clear contents of debug file.
	m_file.open(filename.c_str());
	
	if(m_file.is_open() )
	{
		m_fileopened = true;
		dbg.print("Debug: successfully loaded file '%s'.\n", filename.c_str() );
	}
	else 
	{
		// file failed to open
		dbg.print("Debug: failed to open file '%s'.\n", filename.c_str() );
	}

}

/*
 WARNING: Should only accept c-style strings only. If output is ever cryptic double check 
 that we are not passing c++ Strings instead of char*, do not know how to differentiate if
 fmt is a c-style string (char*) or a C++ String.
 */
void Debug::print(const std::string& fmt, ...)
{
	// cannot print unless a file is opened.
	assert(m_fileopened);
	
    va_start(m_vl, fmt);
    vsnprintf(m_buffer, m_sizebuffer, fmt.c_str(), m_vl);
    va_end(m_vl);
    m_file << m_buffer;
    m_file.flush();
}
Hey guys, I decided that my old debug class wasn't good enough so I looked into how printf worked and discovered variadic functions. This is my first time using them, but I was hoping I could get some feedback.
Last edited by short on Tue Jun 01, 2010 2:32 am, edited 4 times in total.
My github repository contains the project I am currently working on,
link: https://github.com/bjadamson
Xeno
Chaos Rift Newbie
Chaos Rift Newbie
Posts: 12
Joined: Fri Jun 05, 2009 5:03 am

Re: Debug class

Post by Xeno »

I believe that when using variadic functions there must be at least one other parameter to the function, however you could change your dbg.print to act like printf by making the first argument a string which holds placeholders such as %s, then you can use vsnprintf to automagically replace the placeholders with the arguments.

Unfortunately since vsnprintf is a C style function, you'd need to use a char * as a buffer instead of a std::string, which kinda goes against the C++ style you're using.

An example will probably make it more clear:

Code: Select all


void Debug::print(const std::string& fmt, ...)
{
    char buffer[256];
    va_start(m_vi, fmt);
    vsnprintf(buffer, 256, fmt.c_str(), m_vi);
    va_end(m_vi);
    m_file << buffer;
    m_file.flush();
}

Then your example would work like:

Code: Select all


dbg.print("loading %s ....", mapname->c_str());

X Abstract X
Chaos Rift Regular
Chaos Rift Regular
Posts: 173
Joined: Thu Feb 11, 2010 9:46 pm

Re: Debug class

Post by X Abstract X »

Since you asked for any ideas I'll just post my logger class, I have no idea what a variadic function is. Mine writes to the console but obviously it can be switched to write to a text file. I'm not sure but I think you might want to make sure you declare a private copy constructor and private assignment operator for the class you have right now.

Code: Select all

#ifndef Logger_H
#define Logger_H

#include <sstream>
#include <iostream>
#include <iomanip>

class Logger {
public:
    Logger() {}
    ~Logger() {}

    template <typename Type>
    Logger& operator<<(const Type& output) {
        std::stringstream stream;
        
        stream << std::setprecision(16) << output;
        
        std::cout << stream.str();

        return(*this);
    }
};

#endif
User avatar
short
ES Beta Backer
ES Beta Backer
Posts: 548
Joined: Thu Apr 30, 2009 2:22 am
Current Project: c++, c
Favorite Gaming Platforms: SNES, PS2, SNES, SNES, PC NES
Programming Language of Choice: c, c++
Location: Oregon, US

Re: Debug class

Post by short »

Code: Select all

Debug(const Debug& d);    // copy constructor needs to be private as well.

Code: Select all

//=operator needs to be private
   Debug& operator=(const Debug &rhs)
   {
   }
Ok I added these to my header, I understand declaring =operator as private being necessary. What I don't know is why Debug() being private is not enough. If I do not declare a constructor with a constant reference of type itself as a parameter will the compiler automatically generate one? I was under the assumption the only constructor the compiler automatically created for the user was the default Debug() (no parameters). Am I wrong?

To be more clear, when I first posted this code I had already declared Debug() as private.

Also, thanks a bunch for helping me out. I edited the first post with some slight changes to your post, :)
My github repository contains the project I am currently working on,
link: https://github.com/bjadamson
User avatar
short
ES Beta Backer
ES Beta Backer
Posts: 548
Joined: Thu Apr 30, 2009 2:22 am
Current Project: c++, c
Favorite Gaming Platforms: SNES, PS2, SNES, SNES, PC NES
Programming Language of Choice: c, c++
Location: Oregon, US

Re: Debug class

Post by short »

X Abstract X wrote:, I have no idea what a variadic function is.
The wikipedia: http://en.wikipedia.org/wiki/Variadic_function

Basically it's how printf can have an undetermined amount of parameters, and now my debug class :)
My github repository contains the project I am currently working on,
link: https://github.com/bjadamson
X Abstract X
Chaos Rift Regular
Chaos Rift Regular
Posts: 173
Joined: Thu Feb 11, 2010 9:46 pm

Re: Debug class

Post by X Abstract X »

Hey you don't have to put the empty body of the assignment operator. And yes, copy constructors are automatically generated so you gotta make it private in this case. Just for future reference, you have to be careful with these default copy constructors because sometimes you MUST write your own. Look up deep vs. shallow copy for a better description than I could give.
User avatar
short
ES Beta Backer
ES Beta Backer
Posts: 548
Joined: Thu Apr 30, 2009 2:22 am
Current Project: c++, c
Favorite Gaming Platforms: SNES, PS2, SNES, SNES, PC NES
Programming Language of Choice: c, c++
Location: Oregon, US

Re: Debug class

Post by short »

X Abstract X wrote:Hey you don't have to put the empty body of the assignment operator. And yes, copy constructors are automatically generated so you gotta make it private in this case. Just for future reference, you have to be careful with these default copy constructors because sometimes you MUST write your own. Look up deep vs. shallow copy for a better description than I could give.
Nah I understand shallow vs deep, I just wasn't aware the compiler generated "2" default constructors.
My github repository contains the project I am currently working on,
link: https://github.com/bjadamson
Post Reply