• Advertisement
Sign in to follow this  

C++ Questions about constructors, pointers, and smart pointers

Recommended Posts

So I have some quick questions about constructors and pointers


Question on constructors:
1. I'm working on this Sprite class and in general sprites need some kind of texture in order to display to the screen. So I have my class looking like this:

class Sprite
{
public:
  Sprite(Texture* texture);
  ~Sprite();
  
  Texture* texture;
  //Other class stuff
}

Now in the current state of my Sprite class would I be correct in that I cannot use it as a member in a different class, because it has no no-arg (default) constructor? That the only way this class could be a member is if it was a pointer?

class SpriteContainer
{
public:
  SpriteContainer();
  ~SpriteContainer();
  
  Sprite singleSprite; //**BAD** not allowed because Sprite has no no-arg (default) constructor
  Sprite* singleSpritePtr; //This is allowed because its a pointer
  
  std::vector<Sprite> sprites; //**BAD** not allowed because Sprite has no no-arg (default) constructor
  std::vector<Sprite*> spites; //This is allowed because its a vector of Sprite pointers
}

I guess my really problem here is that I struggle with when a variable/class should be a pointer or not

2. How do you make an abstract class where there are no methods that should be pure virtual functions?
All the functions of the base class have there implementation, but I also do not want this class to be instantiated

//Should not be able to instantiate this class. Should be an Abstract class
class BaseClass
{
public:
  BaseClass() { x = 0; };
  virtual ~BaseClass() { };

  int x;
  void coolMethod()
  {
    ++x;
  }
}

//Can instantiate this class. coolMethod can be called from this class
class DerivedClass : public BaseClass
{
public:
  DerivedClass();
  ~DerivedClass();
}

 

Questions about smart pointers:
1. I have never used these before, but are smart pointers ok when working with COM objects?
Will the smart pointer automatically call a COM object's Release function or should I wrap my COM object and explicitly call Release in the wrapper class' destructor?

2. Lets say there is a case where I wanted to give back the user of some APIs a pointer to a resource, but I also want them to know that they don't have to worry about cleaning it up. EG There is resource loader that will clean up all loaded resources once the program shuts down. The user has to do/worry about nothing.
What type of smart pointer should I use in a case like this? Should it be a Shared pointer? Or should I make the resource a Unique pointer and then return to the user a raw pointer?

Edited by noodleBowl

Share this post


Link to post
Share on other sites
Advertisement
1 hour ago, noodleBowl said:

Now in the current state of my Sprite class would I be correct in that I cannot use it as a member in a different class, because it has no no-arg (default) constructor? That the only way this class could be a member is if it was a pointer?

No - but you need to construct it when the class that owns the sprite is constructed in the initializer list, like so.

SpriteContainer::SpriteContainer()
  : singleSprite(nullptr)
  {
  }

// or

SpriteContainer::SpriteContainer(Texture* texture)
  : singleSprite(texture)
  {
  }

 

1 hour ago, noodleBowl said:

2. How do you make an abstract class where there are no methods that should be pure virtual functions?
All the functions of the base class have there implementation, but I also do not want this class to be instantiated

You could try making the base class's constructors private, or use C++'11's "=delete" syntax to explicitly delete them.

1 hour ago, noodleBowl said:

1. I have never used these before, but are smart pointers ok when working with COM objects?
Will the smart pointer automatically call a COM object's Release function or should I wrap my COM object and explicitly call Release in the wrapper class' destructor?

Yes, in fact the Windows SDK provides smart pointers specifically for working with COM pointers.

1 hour ago, noodleBowl said:

2. Lets say there is a case where I wanted to give back the user of some APIs a pointer to a resource, but I also want them to know that they don't have to worry about cleaning it up. EG There is resource loader that will clean up all loaded resources once the program shuts down. The user has to do/worry about nothing.
What type of smart pointer should I use in a case like this? Should it be a Shared pointer? Or should I make the resource a Unique pointer and then return to the user a raw pointer?

The usual approach is to just use a raw pointer or a reference and ensure that the non-owning class never outlives the owner of the resource. If ownership is being shared, then shared_ptr for the owners and weak_ptr (if they can outlive the owners) or raw pointers (if they can't) for the non-owners. Most of the time you're not likely to want shared ownership, though.

Edited by Oberon_Command

Share this post


Link to post
Share on other sites
2 hours ago, noodleBowl said:

I guess my really problem here is that I struggle with when a variable/class should be a pointer or not

If you want to indicate another object elsewhere, the options are either a pointer (which can be NULL) or a reference (which cannot be NULL) to that other object. 

If you have an object that is part of the thing you are creating rather than located elsewhere, you can create the instance directly as part of your object, or as a local variable in your function body.

Dynamic allocation with new and delete are objects created elsewhere -- they're on the heap -- so you need a pointer to point to them.  However, modern code should typically use smart pointers rather than raw memory allocations.

2 hours ago, noodleBowl said:

How do you make an abstract class where there are no methods that should be pure virtual functions?
All the functions of the base class have there implementation, but I also do not want this class to be instantiated

Expanding on Oberon_Command's comment here.

The easiest way is to make at least one pure virtual function.  That is:  virtual SomeFunction() = 0;

If you want it to implement ALL the functions, you'll need to use the "=delete" on the automatically generated functions of constructor, copy constructor, move constructor, assignment, move assignment, and destructor.  

Going further, you should keep your virtual functions private, or rarely, protected. The only major exception (which is covered in the article) is virtual destructors where you use polymorphic destruction, and those must be public. Derived classes should override and customize behavior rather than rewrite it completely.

2 hours ago, noodleBowl said:

EG There is resource loader that will clean up all loaded resources once the program shuts down. The user has to do/worry about nothing.

Object lifetime is a major concern in game code.  The developer ALWAYS needs to worry about it.

Again expounding on Oberon_Command's answer, the easiest approach is to require that the code using it never outlives the object.  In your game this is often implemented through rules. For example, a rendering tool might have the rule:  Returns a pointer to the rendering object, the pointer expires at the beginning of the next graphics frame.  A simulation call might have the rule:  Only valid during Update(), returns a pointer to the game object, the pointer expires at the end of the Update() process.  Pointers to objects in a container may be invalidated when items are added or removed. Pointers within an object may be valid the entire time the object exists, assuming the constructor completed rather than throwing an exception.  Everything has its own rule. This type of use is by far the most common practice, and works well if you have clear ownership of objects.  One thing owns the object and the object's lifetime, other code can reference the object within the specified rules.

If you want a fire-and-forget object you can pass along a unique_ptr that properly cleans up when the caller is done. These should not refer to other objects unless you can also guarantee (either through code or through policy) that the smart pointer never outlives the object being referenced.

Yet another option is an object handle rather than a pointer.  Effectively you assign a number (or a structure with that number) which applies to all the things you create, then return that instead of a pointer.  The handle can exist for the duration of the program. Callers need to ask the system to do work using that handle, or to return a pointer to the thing in the handle, but the caller needs to respect that the handle might be invalid.  An example is a file handle in C.  You can create a file and get the file handle, such as handle 37, and manipulate that handle.  Eventually you close that file handle.  If you try to manipulate the file handle after it is closed the function will provide a suitable error rather than crash.

In large or complex games it is extremely difficult to get shared ownership working correctly.  It is easy to accidentally create circular dependencies that are leaked, or have other issues with no clear owner and no clear responsibility.  It isn't worth the headache.

Share this post


Link to post
Share on other sites

Thanks for the info on the smart pointers and the init list!

11 hours ago, Oberon_Command said:

You could try making the base class's constructors private

10 hours ago, frob said:

The easiest way is to make at least one pure virtual function.  That is:  virtual SomeFunction() = 0;

Definitely thought about this as an option

I have also seen this weird pure virtual destructor thing, where the destructor is pure virtual and body of the destructor is still defined. But I'm not sure about this... seems kind of hacky

//In header file
class BaseClass
{
  BaseClass();
  ~BaseClass() = 0;
}

//In cpp file
BaseClass::BaseClass()
{
}

BaseClass::~BaseClass()
{
}

 

Share this post


Link to post
Share on other sites
On 11/24/2017 at 11:37 AM, noodleBowl said:

I have also seen this weird pure virtual destructor thing, where the destructor is pure virtual and body of the destructor is still defined. But I'm not sure about this... seems kind of hacky

It is the idiomatic and de facto standard way of indicating a class is a non-instantiable virtual base class.  There is nothing hacky about it.

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  

  • Advertisement
  • Advertisement
  • Popular Tags

  • Advertisement
  • Popular Now

  • Similar Content

    • By Hawkblood
      I've been away for a VERY long time, so if this topic has already been discussed, I couldn't find it.
      I started using VS2017 recently and I keep getting warnings like this:
      1>c:\program files (x86)\microsoft directx sdk (june 2010)\include\d3d10.h(609): warning C4005: 'D3D10_ERROR_FILE_NOT_FOUND': macro redefinition (compiling source file test.cpp) 1>C:\Program Files (x86)\Windows Kits\10\Include\10.0.16299.0\shared\winerror.h(54103): note: see previous definition of 'D3D10_ERROR_FILE_NOT_FOUND' (compiling source file test.cpp) It pops up for various things, but the reasons are all the same. Something is already defined.....
      I have DXSDK June2010 and referencing the .lib and .h set correctly (otherwise I wouldn't get this, I'd get errors)
      Is there a way to correct this issue or do I just have to live with it?
       
      Also (a little off-topic) the compiler doesn't like to compile my code if I make very small changes.... What's up with that? Can I change it? Google is no help.
    • By lonewolff
      Hi guys,
      I am having problems with trying to perform a basic 'shift left' on a char.
      char temp[1]; temp[0] = buffer[0] << 1; // buffer[0] is 0xff After this I have temp[0] writing to a file. Instead of being the expected 0x7F it is written as 0xF8.
      Any guidance on what I am doing wrong would be awesome.
      Thanks in advance
    • By sergio2k18
      Hi all
      this is my first post on this forum.
      First of all i want to say you that i've searched many posts on this forum about this specific argument, without success, so i write another one....
      Im a beginner.
      I want use GPU geometry clipmaps algorithm to visualize virtual inifinte terrains. 
      I already tried to use vertex texture fetch with a single sampler2D with success.
       
      Readed many papers about the argument and all speak about the fact that EVERY level of a geometry clipmap, has its own texture. What means this exactly? i have to 
      upload on graphic card a sampler2DArray?
      With a single sampler2D is conceptually simple. Creating a vbo and ibo on cpu (the vbo contains only the positions on X-Z plane, not the heights)
      and upload on GPU the texture containing the elevations. In vertex shader i sample, for every vertex, the relative height to te uv coordinate.
      But i can't imagine how can i reproduce various 2d footprint for every level of the clipmap. The only way i can imagine is follow:
      Upload the finer texture on GPU (entire heightmap). Create on CPU, and for each level of clipmap, the 2D footprints of entire clipmap.
      So in CPU i create all clipmap levels in terms of X-Z plane. In vertex shader sampling these values is simple using vertex texture fetch.
      So, how can i to sample a sampler2DArray in vertex shader, instead of upload a sampler2D of entire clipmap?
       
       
      Sorry for my VERY bad english, i hope i have been clear.
       
    • By mangine
      Hello. I am developing a civ 6 clone set in space and I have a few issues. I am using Lua for the logic and UI of the game and c++ directx 12 for the graphics. I need a way to send information between Lua and c++ occasionally and was wondering what is the best and most flexible (and hopefully fast) way to do this. Don't forget that I also need to send things from c++ back to Lua. I know of a lua extension called "LuaBridge" on github but it is a little old and I am worried that it will not work with directx 12. Has anybody done something similar and knows a good method of sending data back and forth? I am aware that Lua is used more and more in the industry and surely plenty of AAA game programmers know the answer to this. I want a good solution that will hopefully still be viable code in a couple of years...
    • By owenjr
      Hi there.
      I'm pretty new to this and I don't know if it has been asked before, but here I go.
      I'm developing a game using SFML and C++.
      I would like to use the "Tiled" tool to load maps into my game but I don't actually find any tutorial or guide on how to exaclty use it (I know that I have to read an XML file and stuff). I just step into diverse projects that make all a mess. 
      Anyone knows where can I find good information to make my map loader by myself?
      Thanks in advantage!!
  • Advertisement