Sign in to follow this  

Passing Objects by Reference.

This topic is 4276 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

What I want done: pass around 1 object. What is being done: 2 objects are created. Which object? : an object from class Config The below are the source files
//main.cpp
#include "Singleton.h"
#include "Print.h"
#include "Cookie.h"
#include "Parameter.h"
#include "Path.h"
#include "Config.h"
#include "Skin.h"

typedef Singleton<Print> print;

int main(){

	Cookie mainCookie;
	Parameter mainParameter;
	Path mainPath;
	Config mainConfig;

	mainParameter.SetParameter();
	mainPath.SetPath();

	print::Instance().SetCookie( mainCookie );
	print::Instance().SetParameter( mainParameter );
	print::Instance().SetPath( mainPath );
	print::Instance().SetConfig( mainConfig );

	if ( mainParameter.TestKey("db") && mainParameter.GetParameterValue("db") != "" ){
		if (  mainParameter.TestKeyType("action") == "input" ){
			//Skin skin(cookie,this,that,last,input.cgi)
			//input action
		}
		else if (  mainParameter.TestKeyType("action") == "delete" ){
			//delete action
		}
		else{
			print::Instance().Header( "success" );
			mainConfig.SetConfig( "./system/db/" + mainParameter.GetParameterValue("db") + "/config.cgi" );
			print::Instance().pConfig();
			std::cout << &mainConfig;
			std::cout << "./system/db/" << mainParameter.GetParameterValue("db") << "/config.cgi";
			Skin skin("system/skins/list.shenu", mainCookie, mainParameter, mainPath, mainConfig );
		}
	}
	else{
		print::Instance().Header( "yesh" );
		print::Instance().Error("no_db", "");
	}

	return 0;
}


//Print.h
#if !defined(PRINT)
#define PRINT
#include <string>
#include <map>
#include <iostream>
#include "Cookie.h"
#include "Parameter.h"
#include "Path.h"
#include "Config.h"
#include "Skin.h"

//header
class Print {
	public:
		Print();

		void Error( std::string, std::string );
		std::string ErrorMessage( std::string, std::string );

		void Header( std::string );
		void Header( std::string, std::string );
		void Body();
		void Body( std::string );
		void Tail();
		void Tail( std::string );

		void pCookie( );
		void pParameter( );
		void pPath( );
		void pConfig( );
		void SetCookie( Cookie& paraCookie );
		void SetParameter( Parameter& paraParameter );
		void SetPath( Path& paraPath );
		void SetConfig( Config& paraConfig );
	//end public:
	private:
		void SoftwareInfo( std::string shenuVersion );
		void CSS( std::map< std::string, std::string > para_fieldData );
		const std::string shenuVersion;

		const static std::string CSSClasses[2][3];
		const static std::string CSSInstances[2][6];

		std::map<std::string, std::string>::const_iterator loop;
		Cookie printCookie;
		Parameter printParameter;
		Path printPath;
		Config printConfig;

	//end private:

};

#endif


//Print.cpp
..
..
void Print::SetConfig( Config& paraConfig ){
	printConfig=paraConfig;
}
..
..







So all in all this is how I set the objects. print::Instance().SetCookie( mainCookie ); print::Instance().SetParameter( mainParameter ); print::Instance().SetPath( mainPath ); print::Instance().SetConfig( mainConfig ); and inside print.h i have Config printConfig; inside print.cpp I have void Print::SetConfig( Config& paraConfig ){ printConfig=paraConfig; } my results: the two objects occupy different memory cells.

Share this post


Link to post
Share on other sites
Hey bud,

Where you declare:

Config printConfig;

It needs to be:

Config& printConfig;

This means that this variable needs to be initialised on creation which means that you need to assign it on creation in the initialisation list of the class it is a member of, or have it assigned on declaration anywhere else. Remember, you can't have a reference without a value because it needs to reference something from the word go. What you are doing is recieving a reference in the function but then making a copy to the member.

Hope that helps,

Dave

Share this post


Link to post
Share on other sites
I am going to declare them as pointers.
I've heard pointers are bug prone b/c they just look sophisticated, but I guess that's like my only alternative. maybe...

because I can't initialize those in the beginning.
because the print is a singleton and thus declared in the global, then that would mean I'm going to have to globalize my container types. but I can't do that.

Share this post


Link to post
Share on other sites
Ok,

You can make those pointer safer by employing the correct use of const. You might also look to auto_ptr which is declared in memory.h as well as the boost pointers.

Hope that helps

Dave

Share this post


Link to post
Share on other sites
okay...

Cookie* printCookie=NULL;
Parameter* printParameter=NULL;
Path* printPath=NULL;
Config* printConfig=NULL;
or

Cookie* printCookie=0;
Parameter* printParameter=0;
Path* printPath=0;
Config* printConfig=0;

neither of these work I get compile errors as the following:

Print.h:46: error: ISO C++ forbids initialization of member `printCookie'
Print.h:46: error: making `printCookie' static
Print.h:46: error: invalid in-class initialization of static data member of non-integral type `Cookie*'
Print.h:47: error: ISO C++ forbids initialization of member `printParameter'
Print.h:47: error: making `printParameter' static
Print.h:47: error: invalid in-class initialization of static data member of non-integral type `Parameter*'
Print.h:48: error: ISO C++ forbids initialization of member `printPath'
Print.h:48: error: making `printPath' static
Print.h:48: error: invalid in-class initialization of static data member of non-integral type `Path*'
Print.h:49: error: ISO C++ forbids initialization of member `printConfig'
Print.h:49: error: making `printConfig' static
Print.h:49: error: invalid in-class initialization of static data member of non-integral type `Config*'

Share this post


Link to post
Share on other sites
Quote:
Original post by Dave
Ok,

You can make those pointer safer by employing the correct use of const. You might also look to auto_ptr which is declared in memory.h as well as the boost pointers.

Hope that helps

Dave


Thanks.
I know nothing about pointers.
this is my first time using them lool

Share this post


Link to post
Share on other sites
Are these declared as static variables inside the singleton class? If so, they need to be declared in the CPP file of the singleton, or, by the looks of it, in the main file you posted in the OP.

Dave

Share this post


Link to post
Share on other sites
This Compiles:
Cookie* printCookie;
Parameter* printParameter;
Path* printPath;
Config* printConfig;


These Don't:
Cookie* printCookie=NULL;
Parameter* printParameter=NULL;
Path* printPath=NULL;
Config* printConfig=NULL;

Cookie* printCookie=0;
Parameter* printParameter=0;
Path* printPath=0;
Config* printConfig=0;

Cookie& printCookie;
Parameter& printParameter;
Path& printPath;
Config& printConfig;


I read somewhere that if I don't null out my pointers I'm setting up time bombs.

Share this post


Link to post
Share on other sites
okay this gets really funny.
So everything worked out well, even without nulling my pointers.
and when everything worked fine, the results were:

Config:0x2383 (some # i forgot)
Name: [LangList] Value: [euc-kr]
Name: [SnAccessWrite] Value: [1]
Name: [SnAdminHome] Value: [http://www.s]
Name: [SnAdminMail] Value: [yourmail@]
Name: [SnAdminName] Value: [user]
Name: [SnBackAtt] Value: [1]
Name: [SnBackPos] Value: [3]
Name: [SnBackPos2] Value: [2]

Config:0xbfbfe890
Name: [LangList] Value: [euc-kr]
Name: [SnAccessWrite] Value: [1]
Name: [SnAdminHome] Value: [http://www.s]
Name: [SnAdminMail] Value: [yourmail@]
Name: [SnAdminName] Value: [user]
Name: [SnBackAtt] Value: [1]
Name: [SnBackPos] Value: [3]
Name: [SnBackPos2] Value: [2]










So, I performed a little test.


#include "Singleton.h"
#include "Print.h"
#include "Cookie.h"
#include "Parameter.h"
#include "Path.h"
#include "Config.h"
#include "Skin.h"

typedef Singleton<Print> print;


int main(){

Cookie mainCookie;
Parameter mainParameter;
Path mainPath;
Config mainConfig;

mainParameter.SetParameter();
mainPath.SetPath();

print::Instance().SetCookie( mainCookie );
print::Instance().SetParameter( mainParameter );
print::Instance().SetPath( mainPath );
//print::Instance().SetConfig( mainConfig );

//print::Instance().pPath();
//print::Instance().pParameter();
//print::Instance().pCookie();
//print::Instance().pPath();

if ( mainParameter.TestKey("db") && mainParameter.GetParameterValue("db") != "" ){
if ( mainParameter.TestKeyType("action") == "input" ){
//Skin skin(cookie,this,that,last,input.cgi)
//input action
}
else if ( mainParameter.TestKeyType("action") == "delete" ){
//delete action
}
else{
print::Instance().Header( "success" );
mainConfig.SetConfig( "./system/db/" + mainParameter.GetParameterValue("db") + "/config.cgi" );
print::Instance().pConfig();
std::cout << &mainConfig;
std::cout << "./system/db/" << mainParameter.GetParameterValue("db") << "/config.cgi";
Skin skin("system/skins/list.shenu", mainCookie, mainParameter, mainPath, mainConfig );
}
}
else{
print::Instance().Header( "yesh" );
print::Instance().Error("no_db", "");
}

return 0;
}





This is the main thing that has been changed: I commented it out
//print::Instance().SetConfig( mainConfig );

and the results?

Config:0xbfbfe890
Name: [LangList] Value: [euc-kr]
Name: [SnAccessWrite] Value: [1]
Name: [SnAdminHome] Value: [http://www.s]
Name: [SnAdminMail] Value: [yourmail@]
Name: [SnAdminName] Value: [user]
Name: [SnBackAtt] Value: [1]
Name: [SnBackPos] Value: [3]
Name: [SnBackPos2] Value: [2]

the pointer still points to the same thing!!
and the thing is still there!!
what the hell!!
so, I'm guessing that this is the so called memory leakage.
And this is why I should null them.
but I get compile errors when trying to null them.

Share this post


Link to post
Share on other sites
Quote:
Original post by Tradone
This Compiles:
Cookie* printCookie;
Parameter* printParameter;
Path* printPath;
Config* printConfig;


These Don't:
Cookie* printCookie=NULL;
Parameter* printParameter=NULL;
Path* printPath=NULL;
Config* printConfig=NULL;

Cookie* printCookie=0;
Parameter* printParameter=0;
Path* printPath=0;
Config* printConfig=0;

Cookie& printCookie;
Parameter& printParameter;
Path& printPath;
Config& printConfig;


I read somewhere that if I don't null out my pointers I'm setting up time bombs.


You are defining each of them three times. It should look like this:

Cookie* printCookie=NULL;
Parameter* printParameter=NULL;
Path* printPath=NULL;
Config* printConfig=NULL;


Also, what you read is likely just refering to setting them to NULL after (but not before) you delete them, not when you create them.

Share this post


Link to post
Share on other sites
Quote:
Original post by Roboguy

You are defining each of them three times. It should look like this:

Cookie* printCookie=NULL;
Parameter* printParameter=NULL;
Path* printPath=NULL;
Config* printConfig=NULL;


I did do them only once,
I did them once three times using each method each time I tried
and I believe I got the same compile errors:

Print.h:46: error: ISO C++ forbids initialization of member `printCookie'
Print.h:46: error: making `printCookie' static
Print.h:46: error: invalid in-class initialization of static data member of non-integral type `Cookie*'
Print.h:47: error: ISO C++ forbids initialization of member `printParameter'
Print.h:47: error: making `printParameter' static
Print.h:47: error: invalid in-class initialization of static data member of non-integral type `Parameter*'
Print.h:48: error: ISO C++ forbids initialization of member `printPath'
Print.h:48: error: making `printPath' static
Print.h:48: error: invalid in-class initialization of static data member of non-integral type `Path*'
Print.h:49: error: ISO C++ forbids initialization of member `printConfig'
Print.h:49: error: making `printConfig' static
Print.h:49: error: invalid in-class initialization of static data member of non-integral type `Config*'
I should try making them a const


Quote:
Original post by Roboguy
Also, what you read is likely just refering to setting them to NULL after (but not before) you delete them, not when you create them.

Right. Thanks

Share this post


Link to post
Share on other sites
Quote:
Original post by Tradone
Quote:
Original post by Roboguy

You are defining each of them three times. It should look like this:

Cookie* printCookie=NULL;
Parameter* printParameter=NULL;
Path* printPath=NULL;
Config* printConfig=NULL;


I did do them only once,
I did them once three times using each method each time I tried
and I believe I got the same compile errors:

Print.h:46: error: ISO C++ forbids initialization of member `printCookie'
Print.h:46: error: making `printCookie' static
Print.h:46: error: invalid in-class initialization of static data member of non-integral type `Cookie*'
Print.h:47: error: ISO C++ forbids initialization of member `printParameter'
Print.h:47: error: making `printParameter' static
Print.h:47: error: invalid in-class initialization of static data member of non-integral type `Parameter*'
Print.h:48: error: ISO C++ forbids initialization of member `printPath'
Print.h:48: error: making `printPath' static
Print.h:48: error: invalid in-class initialization of static data member of non-integral type `Path*'
Print.h:49: error: ISO C++ forbids initialization of member `printConfig'
Print.h:49: error: making `printConfig' static
Print.h:49: error: invalid in-class initialization of static data member of non-integral type `Config*'
I should try making them a const

Ahh, they're in a class. In that case, initialize them in the constructor.

Quote:

Quote:
Original post by Roboguy
Also, what you read is likely just refering to setting them to NULL after (but not before) you delete them, not when you create them.

Right. Thanks


Just want to clarify a bit on this point. It will not cause a crash to delete a NULL pointer (that's actually why you should set it to NULL after you delete it), but you should not have code that sets a pointer to NULL than immediately deletes it, without ever deleting it before you set it to NULL. Basically, you should not have code that looks like this:

Example* example = new ...;
// No code which deletes example here...
example = NULL;
delete example;

This would not crash, but it would cause a memory leak.

Code like this, however, is fine:

Example* example = new ...;
delete example;
example = NULL; // You want this line here because if something deletes it again, it will not crash. If this line were not here, it would crash.
// ... Nothing else is assigned to example ...
delete example; // This line actually does nothing, because example is NULL.

Share this post


Link to post
Share on other sites
[lol] i'm so dumb, and such a novice.
I'm not allowed to initialize in a header lol.

Quote:
Original post by Roboguy

Code like this, however, is fine:

Example* example = new ...;
delete example;
example = NULL; // You want this line here because if something deletes it again, it will not crash. If this line were not here, it would crash.
// ... Nothing else is assigned to example ...
delete example; // This line actually does nothing, because example is NULL.


Actually [lol],
I was honestly just about to delete what was NULL.
or what might be NULL, because the code is based on dynamic data, and sometimes certain data are not submitted and then in that case, i would be deleting a NULL.

so I should do something like

Example* example=NULL;
...
..
dynamic code
..
...
if ( example == NULL )
example=new Example;

delete example;
example=NULL;


so.. yea. Thanks for the data!
btw, this is the destructor

Print::~Print(){
const std::string shenuVersion = "7.000";

if ( printCookie==NULL )
printCookie=new Cookie;
if ( printParameter==NULL )
printParameter=new Parameter;
if ( printPath==NULL )
printPath=new Path;
if ( printConfig==NULL )
printConfig=new Config;

delete printCookie;
delete printParameter;
delete printPath;
delete printConfig;

printCookie=NULL;
printParameter=NULL;
printPath=NULL;
printConfig=NULL;
}


Share this post


Link to post
Share on other sites
okay..
there seems to be a runtime error.

//main.cpp
#include "Singleton.h"
#include "Print.h"
#include "Cookie.h"
#include "Parameter.h"
#include "Path.h"
#include "Config.h"
#include "Skin.h"

typedef Singleton<Print> print;

int main(){

Cookie mainCookie;
Parameter mainParameter;
Path mainPath;
Config mainConfig;

mainParameter.SetParameter();
mainPath.SetPath();

print::Instance().SetCookie( mainCookie );
print::Instance().SetParameter( mainParameter );
print::Instance().SetPath( mainPath );
print::Instance().SetConfig( mainConfig );

...
...
}

//print.cpp

void Print::SetCookie( Cookie& paraCookie ){
printCookie=paraCookie;
}

void Print::SetParameter( Parameter& paraParameter ){
printParameter=&paraParameter;
}

void Print::SetPath( Path& paraPath ){
printPath=&paraPath;
}

void Print::SetConfig( Config& paraConfig ){
printConfig=&paraConfig;
}





seems like that is what is causing the runtime errors.





Share this post


Link to post
Share on other sites
Quote:
Original post by Tradone
Quote:
Original post by Roboguy

Code like this, however, is fine:

Example* example = new ...;
delete example;
example = NULL; // You want this line here because if something deletes it again, it will not crash. If this line were not here, it would crash.
// ... Nothing else is assigned to example ...
delete example; // This line actually does nothing, because example is NULL.


Actually [lol],
I was honestly just about to delete what was NULL.
or what might be NULL, because the code is based on dynamic data, and sometimes certain data are not submitted and then in that case, i would be deleting a NULL.

so I should do something like

Example* example=NULL;
...
..
dynamic code
..
...
if ( example == NULL )
example=new Example;

delete example;
example=NULL;


so.. yea. Thanks for the data!


No, deleting something which is NULL is fine. My point is that you should not allocate memory (with new) for something, then NULL it before you delete it at all. The memory that it pointed to before it was NULL will be lost, and will create a memory leak. You should set it to NULL after you delete it so if you delete it again, nothing bad will happen (it will just do nothing).

Quote:
Original post by Tradone
okay..
there seems to be a runtime error.
*** Source Snippet Removed ***

seems like that is what is causing the runtime errors.


What sort of runtime errors? Crashes? If so, what line are they occuring on?

Share this post


Link to post
Share on other sites
is it good practice to NULL it even knowing that I won't ever use that pointer again period?

and for the runtime error
I don't think I'm getting any errors.
I assume there fault in this source code below somewhere

//main.cpp
#include "Singleton.h"
#include "Print.h"
#include "Cookie.h"
#include "Parameter.h"
#include "Path.h"
#include "Config.h"
#include "Skin.h"

typedef Singleton<Print> print;

int main(){

Cookie mainCookie;
Parameter mainParameter;
Path mainPath;
Config mainConfig;

mainParameter.SetParameter();
mainPath.SetPath();

print::Instance().SetCookie( mainCookie );
print::Instance().SetParameter( mainParameter );
print::Instance().SetPath( mainPath );
print::Instance().SetConfig( mainConfig );

...
...
}

//print.cpp

void Print::SetCookie( Cookie& paraCookie ){
printCookie=paraCookie;
}

void Print::SetParameter( Parameter& paraParameter ){
printParameter=&paraParameter;
}

void Print::SetPath( Path& paraPath ){
printPath=&paraPath;
}

void Print::SetConfig( Config& paraConfig ){
printConfig=&paraConfig;
}



and if just in case there isn't a problem with the above source code I'm currently breaking it down.

Share this post


Link to post
Share on other sites
Quote:
Original post by Tradone
is it good practice to NULL it even knowing that I won't ever use that pointer again period?

It can't hurt.

Quote:

and for the runtime error
I don't think I'm getting any errors.
I assume there fault in this source code below somewhere
*** Source Snippet Removed ***

and if just in case there isn't a problem with the above source code I'm currently breaking it down.


I don't see any problem with that code. Also, what is the runtime error? Is it crashing? If so, what line?

Share this post


Link to post
Share on other sites
Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator, webmaster@dummy-host.example.com and inform them of the time the error occurred, and anything you might have done that may have caused the error.

More information about this error may be available in the server error log.


-----------------------------------------------------------------------------
this is what I get, it's run on the web.
nothing recorded on the error log,
no .core files.
no nothing, i need to debug and make it work. lol
this is awful.
when this happens, usually i start from scratch.
and build one thing over on top until I get it right.
I waste so much time, and get extremely frustrated

Share this post


Link to post
Share on other sites
Runtime Error:

#include "Singleton.h"
#include "Print.h"
#include "Cookie.h"
#include "Parameter.h"
#include "Path.h"
#include "Config.h"
#include "Skin.h"

typedef Singleton<Print> print;


int main(){
print::Instance().Header( "success" );
Config mainConfig;
print::Instance().SetConfig( mainConfig );
return 0;
}




No Runtime Error:

#include "Singleton.h"
#include "Print.h"
#include "Cookie.h"
#include "Parameter.h"
#include "Path.h"
#include "Config.h"
#include "Skin.h"

typedef Singleton<Print> print;


int main(){
print::Instance().Header( "success" );
Config mainConfig;
//print::Instance().SetConfig( mainConfig );
return 0;
}




Runtime Error:
print::Instance().SetConfig( mainConfig );

No Runtime Error:
//print::Instance().SetConfig( mainConfig );


more code snippet:

//inside print.cpp
void Print::Header( std::string title ){
Header( title, "" );
}

void Print::Header( std::string title, std::string headerPath ){
std::cout<< "Content-type: text/html\n\n";
//get cookies
std::cout<< "<html>\n";
std::cout<< "<head>\n";
std::cout<< "<title>" << title << "</title>\n";
if ( headerPath != "" ){
//display contents of the path.
}
std::cout<< "</head>\n";
}

void Print::SetConfig( Config& paraConfig ){
printConfig=&paraConfig;
}

void Print::SetConfig( Config& paraConfig ){
printConfig=&paraConfig;
}


Share this post


Link to post
Share on other sites
Using smart pointers makes things a big easier, and you have to worry about less stuff when using them. You can pass smart pointers like normal(non-pointer) objects, smart pointers also clean up after themselves by deleting what was created when they lose scope.

For pointers which get passed around, used shared_ptr like so:


#include <boost/shared_ptr.hpp>
boost::shared_ptr< Path> mainPath( new Path);
mainPath->SetPath();


To make it a bit easier to read you an use a typedef.


typedef boost::shared_ptr< Path > PathPtr;
PathPtr mainPath( new Path );
mainPath->Setpath();


Then your print function def would look like:

void SetPath( PathPtr paraPath );


The shared pointer will track how many references of itself are out there, and when they are all released it will delete object from memory. Since you are storing pointers to objects created somewhere else, you may run across a problem if you delete an object in one place and try to access it later another. Smart pointers help prevent this problem by taking care of the deletion itself keeping you from having to worry about it.

You can pick boost up at http://www.boost.org

Share this post


Link to post
Share on other sites
okay I found the root cause of the runtime errors:

Print::~Print(){

//delete printCookie;
//delete printParameter;
//delete printPath;
//delete printConfig;

//printCookie=NULL;
//printParameter=NULL;
//printPath=NULL;
//printConfig=NULL;
}


works fine when commented out.
for reference, the print object is a singleton.



I think I'm not having a fully qualitied understanding of when constructors and destructors are called and such. I'll probably pick it up along the way.

Thanks for the tips on the smart pointers and shared pointers.
I will definately look through those, but I would like to first learn how to do it the hard way.

Share this post


Link to post
Share on other sites
Quote:
Original post by Zahlman
First tell me why you think you need pointers here, and then I'll see what I can do to help.


so that I don't have to make two objects that share the same informations.
I can pass it by reference but then I would have to initialize them in the constructor in the beginning, and I'm not in a position to do that.

Share this post


Link to post
Share on other sites

This topic is 4276 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this