Jump to content
  • Advertisement
Sign in to follow this  
Eldritch

Passing structs as parameters to function

This topic is 3764 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

Hi, to explain what I am trying to do, consider the following code:
class CObject
{
};

struct SObjectAttrib
{
	int id;
	const char* name;
};

class CObjectFactory
{
public:

	CObject* Create(SObjectAttrib)
	{
		return new CObject;
	}

	void Destroy(CObject* pObj)
	{
		if (pObj != NULL)
		{
			delete pObj;
			pObj = NULL;
		}
	}
};

int main(void)
{
	CObjectFactory of;

	CObject* obj = of.Create(SObjectAttrib{0, "Object1"});
	of.Destroy(obj);

	return 1;
}


This line: CObject* obj = of.Create(SObjectAttrib{0, "Object1"}); Is what I'd like to be able to do. Is it possible to initiate a struct in this way, or do I really have to initiate it before passing it as a param? What I'm trying to achieve is less code when creating my objects (could be hundreds of them). Is this possible, or do I have to initiate my struct before passing it as a parameter?

Share this post


Link to post
Share on other sites
Advertisement
You can do that if you provide an appropriate constructor:

struct SObjectAttrib
{
SObjectAttrib() {} // Default constructor
SObjectAttrib(int nID, const char* szName) : id(nID), name(szName) {}

int id;
const char* name;
};

// And then:
CObject* obj = of.Create(SObjectAttrib(0, "Object1"));



(Note: Normal brackets, not curly ones)

EDIT: Also, you should really take struct parameters as const reference rather than by value.

Share this post


Link to post
Share on other sites
Quote:
Original post by Eldritch
Is it possible to initiate a struct in this way

Not in the current version of C++. It looks like something like that may be possible in a few years when compilers start supporting C++0x, but if you don't want to wait that long you'll just need to use some named temporaries or give your struct a constructor.

Share this post


Link to post
Share on other sites
And off-topic comment:

void Destroy(CObject* pObj)
{
if (pObj != NULL) {
delete pObj;
pObj = NULL;
}
}
Half of the code here is redundant. The following does exactly the same:
void Destroy(CObject* pObj)
{
delete pObj;
}
Since setting local function parameter value to NULL is completely pointless, and delete behaves well if passed NULL pointer.


And while I know this wasn't the point of the example, the if(NULL)delete stanza is too common, when it's really almost never needed.

Share this post


Link to post
Share on other sites
Quote:
Original post by SiCrane
Not in the current version of C++. It looks like something like that may be possible in a few years when compilers start supporting C++0x, but if you don't want to wait that long you'll just need to use some named temporaries or give your struct a constructor.

It's perfectly possible. Since the anonymous struct does not go out of scope before the constructor returns, the anonymous struct can be initialized as a nameless, temporary variable just like Evil Steve demonstrates.

Share this post


Link to post
Share on other sites
structs should always be passed around with a reference or a pointer depending what you prefer:


class CObjectFactory
{
public:

CObject* Create(SObjectAttrib &attr)
{
CObject *obj = new CObject;
obj->setAttr(attr.id, attr.name); //Pass the attributes to the
//objects somehow
return obj;
}

void Destroy(CObject* pObj)
{
if (pObj != NULL)
{
delete pObj;
pObj = NULL; //NOTE: because the pointer is passed to
//the function by value this sets the
//parameter to NULL, not the original.
//You would need a double pointer
}
}

//Like this
void DestroyAndSetNULL(CObject **pObj)
{
//error check
delete (*pObj); //Delete the pointer this pointer points too :P
*pObj = NULL;
}
};

Share this post


Link to post
Share on other sites
Quote:
Original post by Hnefi
It's perfectly possible. Since the anonymous struct does not go out of scope before the constructor returns, the anonymous struct can be initialized as a nameless, temporary variable just like Evil Steve demonstrates.


Did you notice the part about constructors?

Share this post


Link to post
Share on other sites
Quote:
Original post by firstelder_d
structs should always be passed around with a reference or a pointer depending what you prefer:

*** Source Snippet Removed ***
Nitpick: It should always be a reference in C++ unless NULL is a valid value. And it should be const-reference or const-pointer unless the variable is to be modified by the function. That code will give a compile warning (Non-const reference to a temporary passed to Create()).

Share this post


Link to post
Share on other sites
Quote:
Original post by Evil Steve
Nitpick: It should always be a reference in C++ unless NULL is a valid value.

Nitpick: there are very few absolutes in computer programming. This isn't one of them. Small structures with trivial copy constructors are often more optimally passed by value than by const reference. Even larger objects with more complex copy constructors can sometimes be more optimally passed by value if the function itself is complex and can benefit from the additional spatial locality. A profiler can be used to determine which functions may benefit from a change in parameter passing.

Share this post


Link to post
Share on other sites
Quote:
Original post by SiCrane
Quote:
Original post by Evil Steve
Nitpick: It should always be a reference in C++ unless NULL is a valid value.

Nitpick: there are very few absolutes in computer programming. This isn't one of them. Small structures with trivial copy constructors are often more optimally passed by value than by const reference. Even larger objects with more complex copy constructors can sometimes be more optimally passed by value if the function itself is complex and can benefit from the additional spatial locality. A profiler can be used to determine which functions may benefit from a change in parameter passing.
Ok, make that "generally" then [smile]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!