Constructor and copies

Started by
6 comments, last by iMalc 14 years, 10 months ago
In C++, is there a way to implement this behavior:
#include <assert.h>
class A
{
/* ... */
}

int main()
{
  A a1 (1);
  A a2 (2);
  A a3 (1);

  assert (&a1 == &a3);
  assert (&a2 != &a1);
}
Basically, I want to cache the object on its construction. I am not simply passing an int in the real implementation, I'm passing a std::vector <std::string> and if the std::vector <std::string> is the same as a previously constructed object, the object constructed should be identical. I tried to implement this with a static cache, but this didn't work since the "this" pointer cannot be assigned to when we have identified that this object is to be a duplicate. I think this is an impossible task because of the semantics of constructing. Should I just have a purely static class that holds the cache and also constructs an "A" if it is not in the cache, and then returns a pointer to the object. Then this pointer can be used, and all users of A will have to construct their objects through the cache class and work with pointers to A rather than A's. edit:
class AConstructor
{
  static Cache c;  // probably a std::map
  static A* construct (K key)
  { 
    if (key not in c)
      c.add (value_pair (key, new A (key)));
    return c[key];
  }
};

int main()
{
  A* a1 = AConstructor::construct (1);
  A* a2 = AConstructor::construct (1);

  assert (a1 == a2);
}
The problem with this approach is that it involves changing all my code to include pointers to A, which may make sense or not. The actual problem I'm abstracting is I have a set of GLSL shaders with a list of #define's that go along with a generic shader to customize it. Caching shaders allows me to change shaders much less often if objects share the same properties (like, "SHADOWS", or "TEXTURED"). [Edited by - solinent on May 31, 2009 5:34:07 PM]
Advertisement
This is accomplished through flyweight pattern. Boost has an implementation.

What you are going to end up with is PIMPL. Your classes will be pointers to actual data that is managed externally.
&a1 == &a3 is impossible.
Different objects have different addresses.
Quote:Original post by loufoque
&a1 == &a3 is impossible.
Different objects have different addresses.


Its quite possible with some operator overloading. But you should never, ever do it [grin]
I have come to the conclusion that I will use a purely static class to hold and construct boost::shared_ptr to objects. This way I can leave the implementation relatively the same, just change the way I load the class by using the static class to do so. When extending this in the future, I may adopt a more flexible approach, a non-static member approach that gets passed to everything that needs to use the constructed objects.

Do you guys think this is the best option?
Having the class be entirely static may not be necessary. If you take a quick look at the flyweight pattern (mentioned earlier) in wikipedia, you can see that all that really needs to be static is the Hash that contains the pointers and the function to create them. If you are using some sort of weak referencing system, you don't even need a function for releasing the pointers.

The rest of the methods do not necessarily need to be static, which is better for encapsulation purposes.
Quote:Original post by visage
Having the class be entirely static may not be necessary. If you take a quick look at the flyweight pattern (mentioned earlier) in wikipedia, you can see that all that really needs to be static is the Hash that contains the pointers and the function to create them. If you are using some sort of weak referencing system, you don't even need a function for releasing the pointers.

The rest of the methods do not necessarily need to be static, which is better for encapsulation purposes.


Sorry, I was misunderstood slightly.

I have one class called ShaderProgram, which handles loading an entire shader (vertex/fragment shader) in OpenGL. This just allows me to cache uniform values in a shader and store all the program objects. This class is non-static. What I plan on doing is having a bunch of #define 's in my GLSL code defining certain things about the code (like whether it will be textured or not, shaded with phong, environment mapped, refractive, etc). This will be implemented by an extension to the ShaderProgram class, which simply accepts a list of such symbols (like "TEXTURED", "SHADED", "SHADOWS"), and puts them in before the shader is compiled.

The code that puts the constants and loads them into a static cache is of course static. This allows me to separate ShaderProgram from my more abstract less flexible new system involving #define's. To cache these resources and to speed things up (not too many switching between shaders), I want to cache shaders that are the same.

So in the end, I have a generic static class that creates non-static members of another class via a shared_ptr.
Quote:Original post by rip-off
Quote:Original post by loufoque
&a1 == &a3 is impossible.
Different objects have different addresses.


Its quite possible with some operator overloading. But you should never, ever do it [grin]
I know what you're thinking and I second it. Overloading the address-of operator is not for mere mortals! [evil]
"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms

This topic is closed to new replies.

Advertisement