Defining Class Method Convention

Where is this usually placed?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//file.h
namespace example
{
	class CommandConsole
	{
	public:
		void operator<<(const wchar_t* message)
		{
			typedef void (*pConsoleOutput)(int arg1, int arg2, const wchar_t* arg3, int arg4);
			pConsoleOutput ConsoleOutput = (pConsoleOutput)0x0046B490;
					
			ConsoleOutput(0x2F76344, 0x400D, message, 0x0C);
		}
	}cout;
}


Is it normal to declare/define in the same spot like this? Should I move the definition to a new file?
Last edited on
Normally you just declare your class operations like this

1
2
3
4
5
6
7
namespace example
{
    class CommandConsole {
    public:
          void operator<<(const wchar_t*);
    };
}


and later on (for example in a different file)

1
2
3
4
5
6
7
namespace example
{
    void CommandConsole::operator<<(const wchar_t* message)
    {
         blahblah();
    }
}


but i think you dont want to make the operator as a void function. I think you need an op, for something like this

 
    out_console << "Hey i am output!\n" << "But here is more\n";


For this you need to have a return type of CommandConsole itself, because interprets the first output, which have to return another CommandConsole object, so you can use it again for more output. In your example you have another usage, like this.

1
2
    out_console << "Hey i am output!\n"; // this is the only way to output in your code
    out_console << "But here is more\n"; // pretty lame, isnt it? 


Greatings, Maikel
Oh ok, thank you so much =)
Ok, I'm sorry but I'm still a bit stumped here.

1
2
3
4
5
6
7
8
9
10
// Example.h
namespace Example
{
	class CommandConsole
	{
	public:
		CommandConsole& operator<<(const wchar_t* message);

	}cout;
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
//CommandConsole.cpp
#include "Example.h"

namespace Example
{
	CommandConsole& CommandConsole::operator<<(const wchar_t* message)
	{
		typedef void (*pConsoleOutput)(int arg1, int arg2, const wchar_t* arg3, int arg4);
		pConsoleOutput ConsoleOutput = (pConsoleOutput)0x0046B490;
					
		ConsoleOutput(0x2F76344, 0x400D, message, 0x0C);
		return *this;
	}
}


1
2
3
4
5
6
7
8
// main.cpp
#include "Example.h"

int main()
{
    Example::cout << L"to console\n";
    return 0;
}


This gives me the error: one or more multiply defined symbols found
class Example::CommandConsole Example::cout already defined in main.obj

Why is this happening?
Ok I think I figured out the problem on my own.

class whatever
{

}object;

object I assume is static so I must define my object as static if I want the same effect.

1
2
3
4
5
6
7
8
9
10
11
namespace ex
{
	class CommandConsole
	{
	public:
		CommandConsole& operator<<(const wchar_t* message);

	};

	static CommandConsole cout;
}


This works but I would appreciate it if someone could tell me why I can't use my previous form for creating the object and why can't I use that exact same line in the .cpp file?
Your code did not work, because you defined a variable two times in namespace scope in a header file. So in the moment your header file was included in two different files, the compiler saw that in the same scope you tried to define two variables with the same name. That was a name collision and ended up in an error message saying more or less what i am.

Through the static keyword you made cout an object without external linkage solving this prob. BUT. I am not sure if this way of using the static keyword is deprecated (still accepted but could be remove in further verions of C++ standards). Using it for global variables is definitivly deprecated. As far as i know 'global' is just a special case of namespace scope.

In fact static keyword for global variables just say to the compiler that a variable has no external linkage. Thats why no name collision occur if you define it in more than one variable. The Linker does not even look if there is a second cout in main.cpp or Example.cpp.

You could achieve the same with unnamed namespaces, which member you can only access in the file they are defined (because if a namespace has no name, you can’t explicitly use a using directive or using declaration to make the names available elsewhere) You can use it like this:


example.h (based on my own test code)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#ifndef __example_h
#define __example_h

#include <string>

namespace example
{
	class CommandConsole {
	private:
		std::string input;

	public:
		CommandConsole & operator<< (std::string);
		std::string last() const { return input; }
	};

	namespace {
		CommandConsole cout;
	}
}

#endif 



In my oppinion it is defintivly better to define your cout object in your Example.cpp and make a reference declaration in your header file like this:

in Header:
 
     extern CommandConsole cout;



in Example.cpp
 
     CommandConsole cout;


This way the variable will be in memory just once.

Hope its correct now, Maikel
Last edited on
That worked perfectly!

I greatly appreciate the time you've spent helping me to understand these issues. Your posts have been extremely helpful.

Thanks again!
Topic archived. No new replies allowed.