• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
cozzie

Should I include or make a pointer?

9 posts in this topic

Hi,
I've decided to recheck my whole application (3d engine) code structure, including finding the best of using headers, includes and forward declarations.

So far I used the following guidelines (100% used):
- headers don't include other headers
- if my class in a header has a function definition which needs an object of one of my other classes, I use a forward declaration. Example:

// d3d.h
#ifndef D3D_H
#define D3D_H

namespace MyEngine
{

class D3DScene;

class D3D
{
public:
void RenderScene(D3DScene *myScene)
..
...
}

This works for 90% of my code and structure.
Where I go wrong is in the following situation:

// d3d.h
#ifndef D3D_H
#define D3D_H

namespace MyEngine
{

class D3DFont;

class D3D
{
public:
D3DFont justafont; // this line produces the compiler error
...

void function1(D3DFont *fntpointer);
void function2(D3DFont &fntinstance);
void function3(D3DFont fntobject);
};

// d3dfont.h

class D3DFont
{
public:
// vars etc.
};

When I compile this, I get "D3D::justafont' uses undefined class 'MyEngine::D3DFont'
(not 100% the code, but pseudo good enough).

I studied some articles on forward declarations and understand that I can use them in my class header when:
- I pass through a object pointer in one of my member functions (like above; function1)
- I pass through an instance of an object in one of my member functions (like above; function2)
- It's not possible to pass through a complete object in a member function with forwar declaration (instead #include the header with the class definition) (likeabove; function 3)

In short;
- Can I have D3DFont justafont as member of D3D class, not being a pointer or var in a member function, using a forward declaration? (or do I have to include the header where D3DFont is declared?).
Maybe I already have an idea, because using D3DFont *myfonts; in the D3D class compiles without problems..
Only I don't see the logic in having a member variable (font object) declared as a pointer since it's not (as far as I understand).

Any help or advice is really appreciated.
I'm looking for the best way reduce includes in my D3D header in this case, and using forward declarations when possible. Edited by cozzie
0

Share this post


Link to post
Share on other sites
If you are going to start changing members to pointers, you might as well go all the way and use the pimpl idiom.

Either way, there is a maintenance and runtime cost, and you should consider whether it is worthwhile. It's not just a question of good or bad style.
2

Share this post


Link to post
Share on other sites

Thanks for the quick reaction. What do you mean with 'pimpl idiom'?

 

To be honest, I don't see any functional problem or readibility problem using forward declarations for objects what are passed through as pointer or instance in member functions and use includes for class definitions of classes that are an actual member of the other class.

 

What does make it more readable/ logic for (looking at today's size of the app), is drawing a clear line in usage between members within a class and objects that are passed through within member functions.


For example:

 

//d3d.h

#include "d3dskybox.h"

 

namespace myEgine

{

 

class D3Dcamera;

class D3Dsomething;

 

Class D3D

{

public:

    skybox mySkybox;

 

   bool DoSomethingWithCam(D3Dcamera *pCamera);

   void DoSomethingWithSomething(D3Dsomething &pSomeThing)

..

..

};

 

 

To be honest when I write this out, it 'feels good' right away, with the pro's:

- good readable/ clear situation for my to read and write

- no unneccesarry includes in headers

- not making pointers of something that's not a pointer, only to be able to do forward declaration instead of include

 

Do you see any con's?

0

Share this post


Link to post
Share on other sites

As an addition, do you know the difference between:

 

class D3Dskybox;

 

namespace myEngine

 

class D3D

{

    void somefunction(D3Dskybox *pBox);

};

 

and

 

namespace myEngine

 

class D3Dskybox;

 

class D3D

{

    void SomeFunction(D3Dskybox *pBox);

...

...

};

 

The 2nd sounds most logic to me, because D3Dskybox is also a class within the same namespace.

0

Share this post


Link to post
Share on other sites
Thanks for the quick reaction. What do you mean with 'pimpl idiom'?

 

To be honest, I don't see any functional problem or readibility problem using forward declarations for objects what are passed through as pointer or instance in member functions and use includes for class definitions of classes that are an actual member of the other class.

 

I'll let you google for the details, but basically you hide the entire implementation of a class behind a pointer. It reduces the header to the public interface only, but it does come with a cost.

 

If you don't want to go that far, forward declaring types used only in the interface as pointers or references is absolutely worth it.

0

Share this post


Link to post
Share on other sites

For another opinion on headers, I found a useful post awhile back:
http://www.cplusplus.com/forum/articles/10627/

 

Specifically in section 4:

 

 

There are two basic kinds of dependencies you need to be aware of:
1) stuff that can be forward declared
2) stuff that needs to be #included

If, for example, class A uses class B, then class B is one of class A's dependencies. Whether it can be forward declared or needs to be included depends on how B is used within A:


- do nothing if: A makes no references at all to B
- do nothing if: The only reference to B is in a friend declaration
- forward declare B if: A contains a B pointer or reference: B* myb;
- forward declare B if: one or more functions has a B object/pointer/reference
as a parementer, or as a return type: B MyFunction(B myb);
- #include "b.h" if: B is a parent class of A
- #include "b.h" if: A contains a B object: B myb;

 

It sounds like this is what you're doing, although you're limiting your code to the top section of the list. The article does have quite a bit more useful information, though.

0

Share this post


Link to post
Share on other sites
Thanks, the last one in the list was my initial problem.
I'll do some extra checks against the list, though i think most are covered.

With one difference which for me works more readable/ usable:
- if a has an object of b as member, do include
- if a has a array (pointer) of b's i could forward declare bacause it's it's a pointer, but i now use an include for that too (in line with having b as a single object member)
0

Share this post


Link to post
Share on other sites

There's just one thing to remember when thinking about whether you need to provide a full declaration of a class/type, or just a forward declaration: Does the compiler need to know the size of the class/type in question in order to compile the code? That's really all there is to it.

 

Consider the following examples:

// pass-by-pointer. the compiler doesn't need to know what sizeof(MyClass) is, but only that this class exists. a forward declaration suffices.

void Function(MyClass* instance);

 

// pass-by-value. the compiler needs to set aside stack memory for the temporary, hence it needs to know sizeof(LightWeightType). a full declaration is therefore needed.

void Function(LightWeightType value);

 

// a member of a class. in order to determine sizeof(A), sizeof(B) needs to be known. hence, a full declaration is needed.

class A

{

  B member;

};

 

Hope that helps!

0

Share this post


Link to post
Share on other sites

Thanks, that really works as a guideline.

For all but one situation I can explain my current code and how I do it.

 

Only thing I don't get is this:

- Class D3Dscene includes member: class D3Dmesh *meshes;

 

Here I find it a bit doube, on one hand D3Dscene doesn't need to know the size (also not known yet without a 'new' statement), on the other hand it is a member of D3Dscene...

0

Share this post


Link to post
Share on other sites

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  
Followers 0