Jump to content
  • Advertisement


  • Content Count

  • Joined

  • Last visited

Community Reputation

236 Neutral

About scjohnno

  • Rank
  1. The full code, pasted directly into a new project in my copy of VS2008, crashes on the for_each(). If I switch it to use Boost.Bind & Boost.Function (v1.36), without any other changes, it works fine. So yeah, it probably is an implementation bug. I don't have VS2010 to check with, unfortunately.
  2. Does ISprite have a virtual destructor?
  3. scjohnno

    Non-const variable to const pointer

    Quote:Original post by Promethium int const* ptr; // Const pointer to non-const data int *const ptr; // Non-const pointer to const data The comments for these two should be swapped. I think the following always holds true: 'const' always applies to the item to its left, unless there is no item to its left, in which case it applies to the item to its right. For instance: int const x = 0; // const applies to the item to its left, which is the int int const * y = &x; // const applies to int, so it's a non-const pointer to a const int const int const * z = &x; // Both of the consts apply to the int, so it's a non-const pointer to a const int. Emits a warning in VC2008
  4. Quote:Original post by iMalc Yes it's safe. w exists until the end of main, and p exists until the end of operator-> Thanks, this'll make things much less messy. Quote:Original post by iMalc Of course it probably doesn't really make sense to create an object inside operator-> We've written a smart-pointer-like class that stores a boost::weak_ptr<> and a UUID. It has the ability to retrieve the element via either weak_ptr::lock() or by loading from an external database (depending on if the element already exists). Either requires creation of a shared_ptr once the object is locked/loaded, and it's purely a lot cleaner to do: ptr->func(); than ptr.getSharedPtr()->func(); or (*ptr)->func(); ...all over the place (and it gets even messier with iterators). Now, if you're using the one object a lot, it's better to store the shared_ptr rather than construct/destruct a bunch of temporaries (that are, in turn, going to persist/load the object from the DB every time), but for limited uses it's handy (there's a cache anyway, so it won't actually access the DB every time). It might not be the best approach, but it seems to work and fits our needs (our datasets can be potentially huge, so memory is a concern).
  5. I'll put some example code first: #include <boost/shared_ptr.hpp> #include <iostream> struct Foo { ~Foo() { std::cout << "~Foo()\n"; } void test() { std::cout << "test()\n"; } }; struct Wrapper { boost::shared_ptr<Foo> operator->() { boost::shared_ptr<Foo> p(new Foo()); return p; } }; int main() { Wrapper w; w->test(); std::cout << "Test complete.\n"; } In Visual Studio 2008, the above outputs: Quote: test() ~Foo() Test complete. Wrapper::operator-> chains boost::shared_ptr<Foo>::operator->, providing direct access to Foo::test. Is p's lifetime guaranteed to be such that w->test() is safe? (That is, will ~Foo() always come after test()?). It's not 100% apparent to me that the temporary returned by Wrapper::operator-> will continue to exist for the duration of the test() call (though this code in Visual Studio 2008 says otherwise). I'm not exactly sure when p is guaranteed to be destructed (before or after the Foo object is extracted from it?). It's possibly just the somewhat-confusing syntax of overloading operator-> that has me befuddled. As I said, it works in Visual Studio 2008, but the project I'm working on would very much appreciate this behaviour being standard, if anyone can confirm it.
  6. #include <boost/pool/pool_alloc.hpp> #include <boost/shared_ptr.hpp> #include <boost/bind.hpp> struct Item { // Don't need a constructor/destructor or overloaded operators }; typedef boost::shared_ptr<Item> ItemPtr; typedef boost::fast_pool_allocator<Item> ItemPool; ItemPtr createPooledItem(ItemPool &pool) { // The second argument gives the shared_ptr a deleter. When the Item inside // is to be deleted, the shared_ptr will call this deleter. We therefore // don't have to worry about deallocating manually either. // You could also give the shared_ptr itself an allocator as a third argument, // if you wanted the reference count to be pooled as well. return ItemPtr(new (pool.allocate()) Item(), boost::bind(&ItemPool::destroy, ref(pool), _1) ); } int main() { ItemPool pool; { ItemPtr i(createPooledItem(pool)); } } On another note, main cannot legally return void. The standard specifies that it must return int. However, you don't need a return statement inside the function, as it'll return 0 by default once it reaches the end of the function.
  7. scjohnno

    NPC and Object Targeting

    Quote:Original post by jyk I'll go ahead and mention though that APIs of this sort will often provide the option of associating generic user data with its entities (whatever they are); if Ogre has this feature, perhaps you could associate an entity name or ID of some sort with the models, and then query for that information when you get a 'hit' in your picking function. This is correct. Check out Ogre::Entity::setUserObject and Ogre::Entity::getUserObject.
  8. I'm not sure what the syntax is for defining a member function, outside the class definition, with use of the scope operator to resolve ambiguities, unfortunately, and I'd love it if someone could post it. If you don't mind defining the functions in the header, though, it can be accomplished as such: class Sprite : public GameObject, public PipelineObject { public: void PipelineObject::Update( float elapsed ) { if (m_speed != 0.0f) { D3DXVECTOR2 travel = m_vector * m_speed * elapsed; Shift(travel.x, travel.y); } } void GameObject::Update(float elapsed) { } //Do nothing; the other update function takes care of everything }; I'm not sure it's such a wise design decision, though. You're effectively saying that any Sprite MUST be treated as if it were a PipelineObject. That is, if it isn't in a list of PipelineObject*s being Update()ed every frame, it won't work properly in the context of being a GameObject. You can't just treat it as a GameObject and forget that it's a PipelineObject, for whatever reason that may be. The implementation of the class has forced you to use the class in a particular way.
  9. scjohnno

    Melbourne Studio Closures

    Yeah, I think it's going to be some other kind of C++ position for me, or possibly Honours. I finish Uni this year and I'm probably going to be one of the more confident graduates entering the market, but it doesn't mean much against so many experienced people being made redundant. Quote:Original post by jackolantern1 Always sad to see a studio collapse. For one of the few industries that still seems to be finding growth and great sales (Modern Warfare 2, as a recent example), it is wracked by instability. I know that is nothing new to the game industry, as studios and even publishers fold all the time, but all the door closings since the economic recession just seems contradictory to what you may be led to believe from seeing the overall numbers of the game industry. In fact, I remember reading that game sales in Australia are actually up over this time last year. Doesn't seem to be reflected, though.
  10. scjohnno

    Virtual function design question

    I doesn't conform to the interface specified by A, so should I really be an A? Perhaps you can define a new interface, and have somefunc() operate on it separately.
  11. scjohnno

    for_each on class member

    #include <boost/bind.hpp> std::vector<boost::shared_ptr<GUIPanel>> m_Panels; Renderer r; //somewhere else for_each(m_Panels.begin(),m_Panels.end(),boost::bind(&Renderer::drawGUIElement, &r, _1)); There's a way to do it with just the standard library, but I honestly haven't bothered to learn how since I discovered Boost.Bind. Edit: I'm assuming that Renderer::drawGUIElement isn't a static function. If it is, remove the '&r' argument.
  12. Quote:Original post by Decrius I only have void return types (I believe slots cannot return, since a signal can have multiple slots, boost only returns the return value of the last invoked slot...that's too 'random' for me) http://www.boost.org/doc/libs/1_40_0/doc/html/signals2/tutorial.html#id1664370
  13. Quote:Original post by iMalc Quote:Original post by theOcelot This way, you get to keep the default constructor without much extra work.Not sure what you mean by that, but a class is allowed to have more than one constructor, and implementing the default constructor here is trivial as shown. There's really no advantage to requiring a helper function to create the Rect vs a constructor to do it. There is one reason you might want to prefer the factory function: Declaring any constructors renders Rect a non-POD type. It's circumstantial, yes, but it's something to remember.
  14. scjohnno

    Empty try/catch blocks

    Sometimes library code throws exceptions for ridiculous reasons. I'm a big proponent of exceptions, but I still recognise that they can be used in poor ways. For instance, OGRE will throw an exception if you tell it to load a resource that has already been loaded. This is nothing but a pain, as the calling code doesn't care if the resource was loaded previously - all it cares about is if it is loaded after the fact. The code afterward does not change unless the resource could not be loaded at all. So now I have a few empty catch(Ogre::Exception&) blocks in my code. Then again, OGRE does seem to be a perfect example of programmers overusing C++'s features in misguided ways.
  • Advertisement

Important Information

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

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!