Skip to main content
GameDev.net gamedev.net
🔒 Locked

linking problem

Started by original vesoljc Jun 2, 2003 at 8:34 AM 11 replies 1k views
Original Post
original vesoljc
original vesoljc
	class   AbstractInfoString
	{

	public:
	// LIFECYCLE

		inline					AbstractInfoString	();
		inline virtual          ~AbstractInfoString	();

	// OPERATORS

	    
		friend std::ostream&	operator<<			(std::ostream& lStream, 
											AbstractInfoString& lInfoString);

	// OPERATIONS


		inline axpVoid			Log					();

	// ACCESS

	// INQUIRY


		virtual axpString		InfoString			() = 0;

	// VARIABLES


	protected:
	// LIFECYCLE

	// OPERATORS

	// OPERATIONS

	// ACCESS

	// INQUIRY

	// VARIABLES


	private:
	// LIFECYCLE

	// OPERATORS

	// OPERATIONS

	// ACCESS

	// INQUIRY

	// VARIABLES


	};

inline AbstractInfoString::AbstractInfoString()
{

}

inline AbstractInfoString::~AbstractInfoString()
{

}

//================= OPERATORS ===============================================

//================= OPERATIONS ==============================================


inline axpVoid AbstractInfoString::Log()
{
	// do log

}

ostream& operator<< ( ostream& lStream, AbstractInfoString& lRight)
{
    lStream << lRight.InfoString();
    return(lStream);
}
	class   ConcreteMode:
								public	AbstractInfoString
	{

	public:
	// LIFECYCLE


		inline					ConcreteMode		();
		inline					ConcreteMode		(const axpUInt64&);
		inline					ConcreteMode		(const ConcreteMode&);
		inline virtual          ~ConcreteMode		();

	// OPERATORS


		inline ConcreteMode&	operator=			(const ConcreteMode&);

	// OPERATIONS

	// ACCESS


		inline axpVoid			Mode				(const axpUInt64&);

	// INQUIRY


		inline axpUInt64		Mode				();
		inline axpBool			IsMode				(const axpUInt64&);
		inline axpString		InfoString			();

	// VARIABLES


	protected:
	// LIFECYCLE

	// OPERATORS

	// OPERATIONS

	// ACCESS

	// INQUIRY

	// VARIABLES


	private:
	// LIFECYCLE

	// OPERATORS

	// OPERATIONS

	// ACCESS

	// INQUIRY

	// VARIABLES


		axpUInt64				mMode;
	};

//////////////////// PUBLIC /////////////////////////////////////////////////

//================= LIFECYCLE ===============================================


inline ConcreteMode::ConcreteMode():
										AbstractInfoString()
{
	mMode			= 0;
}

inline ConcreteMode::ConcreteMode(const axpUInt64& lNewMode):
										AbstractInfoString()
{
	mMode			= lNewMode;
}

inline ConcreteMode::ConcreteMode(const ConcreteMode& lRight):
										AbstractInfoString()
{
	if(&lRight != this)
	{
		mMode			= lRight.mMode;
	}
}

inline ConcreteMode::~ConcreteMode()
{

}

//================= OPERATORS ===============================================


inline ConcreteMode& ConcreteMode::operator=(const ConcreteMode& lRight)
{
	if(&lRight != this)
	{
		mMode			= lRight.mMode;
	}
	return(*this);
}

//================= OPERATIONS ==============================================

//================= ACCESS ==================================================


inline axpVoid ConcreteMode::Mode(const axpUInt64& lNewMode)
{
	mMode			= lNewMode;
}

//================= INQUIRY =================================================


inline axpUInt64 ConcreteMode::Mode()
{
	return(mMode);
}

inline axpBool ConcreteMode::IsMode(const axpUInt64& lMode)
{
	if(mMode == lMode)
		return(axpTrue);
	else
		return(axpFalse);
}

inline axpString ConcreteMode::InfoString()
{
	axpString		lInfoString;
	axpChar			lBuffer[64];

	sprintf(lBuffer,"%d",mMode);

	lInfoString.append(lBuffer);
	return(lInfoString);
}

/////////////////// PROTECTED ///////////////////////////////////////////////

//================= LIFECYCLE ===============================================

//================= OPERATORS ===============================================

//================= OPERATIONS ==============================================

//================= ACCESS ==================================================

//================= INQUIRY =================================================


/////////////////// PRIVATE /////////////////////////////////////////////////

//================= LIFECYCLE ===============================================

//================= OPERATORS ===============================================

//================= OPERATIONS ==============================================

//================= ACCESS ==================================================

//================= INQUIRY =================================================

//================= INQUIRY =================================================


in main: ConcreteMode mode1; cout << mode1; -> here i get linker error error LNK2001: unresolved external symbol "class std::basic_ostream > & __cdecl axp::operator<<(class std::basic_ostream > &,class axp::AbstractInfoString &)" (??6axp@@ YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV12@AAVAbstractInfoString@0@@Z) Debug/axpBuild11.exe : fatal error LNK1120: 1 unresolved externals Error executing link.exe.
Abnormal behavior of abnormal brain makes me normal...
Pepe
Pepe
Definition of axpString ?

Definition of std::ostream& operator<<(std::ostream& lStream, axpString& lInfoString); ?
original vesoljc
original vesoljc
again

AbstractInfoString header

#ifndef _AXP_ABSTRACTINFOSTRING_H_
#define _AXP_ABSTRACTINFOSTRING_H_

// SYSTEM INCLUDES

#include <iostream>
#include <fstream>
// PROJECT INCLUDES

#include "..\axpBase\axpBase.hpp"
// LOCAL INCLUDES


namespace axp
{

class AbstractInfoString
{

public:
// LIFECYCLE

inline AbstractInfoString ();
inline virtual ~AbstractInfoString ();

// OPERATORS


friend std::ostream& operator<< (std::ostream& lStream,
AbstractInfoString& lInfoString);

// OPERATIONS


inline axpVoid Log ();

// ACCESS

// INQUIRY


virtual axpString InfoString () = 0;

// VARIABLES


protected:
// LIFECYCLE

// OPERATORS

// OPERATIONS

// ACCESS

// INQUIRY

// VARIABLES


private:
// LIFECYCLE

// OPERATORS

// OPERATIONS

// ACCESS

// INQUIRY

// VARIABLES


};

#include "axpAbstractInfoString.inl"

} // namespace axp


#endif // _AXP_ABSTRACTINFOSTRING_H_



inline

//////////////////// PUBLIC /////////////////////////////////////////////////

//================= LIFECYCLE ===============================================


inline AbstractInfoString::AbstractInfoString()
{

}

inline AbstractInfoString::~AbstractInfoString()
{

}

//================= OPERATORS ===============================================

//================= OPERATIONS ==============================================


inline axpVoid AbstractInfoString::Log()
{
// do log

}

//================= ACCESS ==================================================

//================= INQUIRY =================================================


/////////////////// PROTECTED ///////////////////////////////////////////////

//================= LIFECYCLE ===============================================

//================= OPERATORS ===============================================

//================= OPERATIONS ==============================================

//================= ACCESS ==================================================

//================= INQUIRY =================================================


/////////////////// PRIVATE /////////////////////////////////////////////////

//================= LIFECYCLE ===============================================

//================= OPERATORS ===============================================

//================= OPERATIONS ==============================================

//================= ACCESS ==================================================

//================= INQUIRY =================================================

//================= INQUIRY =================================================



source

using namespace axp;
using namespace std;

//////////////////// PUBLIC /////////////////////////////////////////////////

//================= LIFECYCLE ===============================================

//================= OPERATORS ===============================================


ostream& operator<< ( ostream& lStream, AbstractInfoString& lRight)
{
lStream << lRight.InfoString();
return(lStream);
}



ConcreteMode header

#ifndef _AXP_CONCRETEMODE_H_
#define _AXP_CONCRETEMODE_H_

// SYSTEM INCLUDES

// PROJECT INCLUDES

#include "..\axpBase\axpBase.hpp"
#include "..\axpAbstractInfoString\axpAbstractInfoString.hpp"
// LOCAL INCLUDES


namespace axp
{

class ConcreteMode:
public AbstractInfoString
{

public:
// LIFECYCLE


inline ConcreteMode ();
inline ConcreteMode (const axpUInt64&);
inline ConcreteMode (const ConcreteMode&);
inline virtual ~ConcreteMode ();

// OPERATORS


inline ConcreteMode& operator= (const ConcreteMode&);

// OPERATIONS

// ACCESS


inline axpVoid Mode (const axpUInt64&);

// INQUIRY


inline axpUInt64 Mode ();
inline axpBool IsMode (const axpUInt64&);
inline axpString InfoString ();

// VARIABLES


protected:
// LIFECYCLE

// OPERATORS

// OPERATIONS

// ACCESS

// INQUIRY

// VARIABLES


private:
// LIFECYCLE

// OPERATORS

// OPERATIONS

// ACCESS

// INQUIRY

// VARIABLES


axpUInt64 mMode;
};

#include "axpConcreteMode.inl"

} // namespace axp


#endif // _AXP_CONCRETEMODE_H_



source

#include "axpConcreteMode.hpp"

using namespace axp;

//////////////////// PUBLIC /////////////////////////////////////////////////

//================= LIFECYCLE ===============================================

//================= OPERATORS ===============================================

//================= OPERATIONS ==============================================

//================= ACCESS ==================================================

//================= INQUIRY =================================================


/////////////////// PROTECTED ///////////////////////////////////////////////

//================= LIFECYCLE ===============================================

//================= OPERATORS ===============================================

//================= OPERATIONS ==============================================

//================= ACCESS ==================================================

//================= INQUIRY =================================================


/////////////////// PRIVATE /////////////////////////////////////////////////

//================= LIFECYCLE ===============================================

//================= OPERATORS ===============================================

//================= OPERATIONS ==============================================

//================= ACCESS ==================================================

//================= INQUIRY =================================================

//================= INQUIRY =================================================



inline

//////////////////// PUBLIC /////////////////////////////////////////////////

//================= LIFECYCLE ===============================================


inline AbstractInfoString::AbstractInfoString()
{

}

inline AbstractInfoString::~AbstractInfoString()
{

}

//================= OPERATORS ===============================================

//================= OPERATIONS ==============================================


inline axpVoid AbstractInfoString::Log()
{
// do log

}

//================= ACCESS ==================================================

//================= INQUIRY =================================================


/////////////////// PROTECTED ///////////////////////////////////////////////

//================= LIFECYCLE ===============================================

//================= OPERATORS ===============================================

//================= OPERATIONS ==============================================

//================= ACCESS ==================================================

//================= INQUIRY =================================================


/////////////////// PRIVATE /////////////////////////////////////////////////

//================= LIFECYCLE ===============================================

//================= OPERATORS ===============================================

//================= OPERATIONS ==============================================

//================= ACCESS ==================================================

//================= INQUIRY =================================================

//================= INQUIRY =================================================



usage

using namespace axp;
using namespace std;

axpUInt32 main()
{
ConcreteMode mode;
cout << mode << endl;
return(axpTrue);
}



Abnormal behavior of abnormal brain makes me normal...
original vesoljc
original vesoljc
typedef std::string axpString;
Abnormal behavior of abnormal brain makes me normal...
Pepe
Pepe
I think I''ve solved it.

You have operator<< as a friend function in class AbstractInfoString declaration.

BUT you DON''T have a proptotype in the header. It''s implemented in AbstractInfoString.cpp but, as you don''t have declared it, it isn''t visible outside AbstractInfoString.cpp.

Declare it in AbstractInfoString header (out of the class):

ostream& operator<<(ostream&, AbstractInfoString&);



Another solution would be a cast operator from AbstractInfoString to String but I don''t like it.
original vesoljc
original vesoljc
i think we are on the right track, but it still doesn't work, either way...

if i comment out the implementaion of the operator, i still get same error, so this means that the implementaion isn't "called"...

what's bothering me is that i have the same stuff allready working before (i still have the source which is the "same"), with one diffrence, now i'm using namespace's. could this couse problems?

update:
friend std::ostream& operator<< (std::ostream& lStream, AbstractInfoString& lInfoString);
changed to
friend std::ostream& operator<< (std::ostream&, AbstractInfoString&);

still doesnt work

[edited by - original vesoljc on June 2, 2003 4:04:41 PM]
Abnormal behavior of abnormal brain makes me normal...
antareus
antareus
The problem is namespaces and overloaded operators. You''re wanting to overload the one used for streams, which I think resides in namespace std. It definitely does NOT reside in the global namespace (::operator<<) because I have tried that.

Unfortunately, adding functions to namespace std is considered by the C++ standard to be undefined, which means don''t do it.

However you can still use your client code as is, just change the definition of the operator to explicitly use the namespace you wish to put it in. As it is now I believe it is considered ambigious (either namespace could contain the definition).

axp::operator<< 


Then it will work as expected.
--God has paid us the intolerable compliment of loving us, in the deepest, most tragic, most inexorable sense.- C.S. Lewis
original vesoljc
original vesoljc
yup, i figured it out...

so, on one side, "they" are "forcing" us to use namespaces, and on the other side... well, i just dont know how to put it

@antareus
u said that adding functions to std is a "no-no", but as i see it, i specified my operator(overloaded) as a property of my own namespace. so, if using my namespace(and not std), will this still be "problematic"? coz, compiler (vc6) is not giving any ambigious crap
Abnormal behavior of abnormal brain makes me normal...
fizban75
fizban75
It has nothing to do with namespaces at all. It''s about where your operator<< is being defined. Currently, I only see it in the source file, but it need to be in the header in order for it be "visible" to the code that uses it.

Put your code in a namespace or not, that''s your choice. No forcing involved.
Pepe
Pepe
As I told you

YOU DON''T HAVE A PROTOTYPE IN THE HEADER

Obviously, if you comment the implementation the error is the same. The compiler CAN NOT FIND an implementation of operator<< because it is declared in nowhere.

friend keyword is only visible inside class. It is NOT a global declaration, it is NOT a member function.

Listen me and put a prototype (outside the class declaration) in AbstractInfoString header in addition to the friend declaration.
programering
programering

Isn''t it like this then?


example.h



class example
{

/*
constructor and
destructor
*/


// declare prototype doSomething

void doSomething(char *str, int w);

};




example.cpp



#include "example.h"

/*
define
constructor and
destructor
in example class
*/


// define function doSomething in class example

void example::doSomething(char *str, int w)
{
/*
do something
*/

}




usage.cpp



#include "example.h"

int main()
{
example ex();
ex.doSomething("hnjadf", 323); // use the example function


return (0);
}





Anton Karlsson
Klingis Entertainment
Games with silly humor
Pepe
Pepe
No, it''s something like this:

example.h

#ifndef EXAMPLE_H
#define EXAMPLE_H

class aClass {
friend void aFunction(aClass & param);
};

#endif


example.cpp

#include "example.h"

void aFunction() {
// some statements to do something

}


usage.cpp

#include "example.h"

int main() {
aClass example;
aFunction(example);
return (0);
}


This code won''t compile.

The correct version of example.h is:

#ifndef EXAMPLE_H
#define EXAMPLE_H

void aFunction(aClass & param);

class aClass {
friend void aFunction(aClass & param);
};

#endif

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.