Jump to content

TheoLogic

Members
  • Posts

    142
  • Joined

  • Last visited

Blog Comments posted by TheoLogic

  1. Did you read the article?
    I tried but the link pointed to my blog entry...

     

    Strange, I may have made a mistake: http://www.codersource.net/c/c-miscellaneous/c-virtual-destructors.aspx

     

    @Roland: I don't say that you are wrong, making all destructors virtual is just not the right solution. Your base destructor should ALWAYS be virtual, just like you stated. It is a good practise to also make your derived destructor virtual to state that you inherit from a base. If you don't want that your class is inherited from, you shouldn't do that however...

    Maybe to remove the confusion, it's the same idea as:

     

    class Base
    {
    public:
    virtual ~Base();
    virtual void Foo();
    };
    
    class Derived
    {
    virtual ~Derived();
    virtual void Foo();
    };
    

     

    In Derived, you don't need the virtual keywords. But it shows that you overwrite a base implementation of Foo for example.

  2. ALWAYS MAKE DESTRUCTORS VIRTUAL if you not has a good reason no to.

     

    Sorry, but that's what you say to school developers in the first year C++ :). There is a huge performance impact as from you have 1 virtual function. It should actually be the other way around, If you inherit or want you class to be inherited from, make your destructor virtual...

     

    A()
    {
       _pmem = new char[1024];
    }
    
    A()
    :
    _pmem(new char[1024])
    { } //No default initialization. Modern compilers should optimize this...
    

  3. Const functions do not exist in Java, I won't blame your uni teachers :).

     

    Regarding the variable initialization, you should do this:

    struct CollisionHitResponse
    {
           CollisionHitResponse()
           :
           NumEntitie****(0),
           EntityHit(nullptr),
           CollisionPoint(nullptr)
           { }
    
           unsigned int NumEntitie****;
           Entity * EntityHit;
           //unsigned int NumCollisionPoints; //A collision point is only saved if the entity the ray collided with is also saved, so these "count" variables will be the same, making one redundant - in this case, I chose this one.
           TVec3 * CollisionPoint;
    };
    

    You may not rely on the "fact" that another method "may" initialize the variables for you! Also a best practise, if I write "auto blah = new Whatever();" I expect that an initialized object. I often see creation followed by an initialization method, which is just plain evil because you can forget it. I create something that I want to use, so please create it completely.

     

    Did you read the article? As you can see you must use virtual destructors or else the base object won't be destructed! So if you have inheritance, 2 things to do:

    1) Check if the base has a virtual destructor, if not the object is probably not ment to inherit from (eg. std::string, std::vector, ...)

    2) Set your own destructor virtual. This defines that your class may be inherited from or/and that you inherit from another class.

     

    Why pass it as const reference is actually pretty simple. std::string allocates dynamic memory behind the screens, and if you pass it by copy you will get an extra memory allocation. There are 3 possible options.

    void Foo(const std::string& bar) //You will only use bar, no changes allowed. This doesn't create a copy, but a reference to the same object! Performance is good.
    

    void Foo(std::string& bar) //You will change bar, this is the original value that you pass to the function, be careful!!!!!!!!!
    
    std::string blah("whatever");
    Foo(blah); //OK
    Foo("whatever"); //ERROR! You may not bind a temporary to a modifiable lvalue reference (ISO standard). But please note that Visual C++ allows this, also known as the evil extension...
    

    void Foo(std::string blah) //Copy of original string passed to function, ideal if you will perform temporary changes on the string in your function.
    

     

    No problems with sharing, this is the reason why I also like to share code, you learn a lot from other people! My remark to lifetime if probably because I coded for Nintendo DSi in the past. You really need all memory you can get, and having global instances is just not the way to do it. What we did were Singletons which we destroyed if unneeded: MyObject::DestroyInstance(); ftw!

  4. So the application is the owner of those pointers, I can live with that, unless you need to manage the lifetime. If this is not the case, it's a valid (but strange) implementation.

     

    I do however remark some things in your code:

    - Pass complex types as const reference: const std::string& EntityConfigFileName

    - Don't forget your virtual destructors in enhetitence models.

    - Add default constructors to your structs. Initialize the variables, always!

    - Accessors should be const: bool IsExplosive() const;

  5. You have created an object that you may create. If you can use it, do it. If you want to make a secret, just provide a lib or a dll. It's just a dataclass, no more no less. Unnamed namespaces are illogical, you create namespaces to define a scope. If you want to make it private as hell, implement as private and set your implementing class as friend.

     

    I'm going to ask one simple question: Who is the owner of:

    ProjectileListEntry * ActiveProjectileHead = 0;

    ProjectileListEntry * MemToReadFrom = 0;

    ?

  6. Like already said above, this is C.

    Like already said above, confusing.

     

    I follow this rule:

    - Do I need a state? If yes, Class. If no, function (best in a namespace).

    - Singleton or static class? The question here is if I want to control the lifetime. If I want to control the lifetime (eg. for memory consumption), I'll use a singleton, if not I'll use a static class.

     

    I think what you are looking for in modern C++ is the pimpl idiom. The idea is to hide your implementation details in an object. So for example you could have:

     

    namespace YourCompany {
    namespace YourProject {
    namespace YourLogicalNamespaces {
    namespace Details { //Details means implementation detail
    
    class MyObjectPimpl
    {
       //Whatever you have as internals...
    };
    
    } //Details
    
    class MyObject
    {
    private:
       MyObjectPimpl m_pimpl;
       //or std::unique_ptr<MyObjectPimpl> m_pimpl; if you want heap, eg. for memory consumption
    };
    
    } //YourLogicalNamespaces 
    } //YourProject 
    } //YourCompany
    

  7. Even better:

     

    enum TextureMode
    {
       TextureMode_Diffuse, /* = 0 if you want to, but I don't really see the need to...*/
       TextureMode_normal
    };

     

    The main problems with defines are really simple: 'They are not subject to any C++ rule what so ever.' The precompiler just replaces them in place, so you can define them again at a later point in builds, even undefine them, ... with all undefined behavior and strange errors.

  8. - You can optimize VS build times (link).

    - MinGW runtime is embedded in the executable, you can achieve the same with static linking in VS.

    - VS2010 lite SQL intellisense is way better as in VS2008. I see no obvious plus points in code::blocks.

    - VS2010 can stop build on first error with some IDE macro, already implemented in some extensions.

    - VC++ optimizer is one of the best on the market! Even the MS STL optimizations are a blast (funcky meta-programming), that's why compiling takes a tad longer :).

     

    This is my overall opinion, not LE2 related. VS beats every other IDE in easy of use (personal opinion)!

  9. Damn, I want one (or two) of those :blink:.

     

    One day you'll hate XCode, objective C and would wish you could use Visual Studio. If I develop for mac, I code in Visual studio, commit to svn, and update on mac, just because XCode misses all basic development actions and a good window layout. I think I must not say there are no good graphical svn clients (free) for mac, so command line is the way to go... You can customize everything in visual studio, from compiler and linkers, to revision handling etc. Combined with Visual Assist for C++ and Resharper for C# no other IDE can compete. I think it's (little) mistake to say Mac is more like Linux than Windows is. Mac has objective C, one of a kind.

     

    Maybe good to know is that steam mac sales are below charts. I know 3 indie companies who ported for mac, and launched at the release date, and still now they haven't got sufficient revenue to cover the port. Everyone is going to think I'm a mac hater, and in a way I am. I love it for graphical work, but for daily use and development it's really not my preference.

     

    Good to hear you're making progress! I have some spare time soon, and I'm thinking to make a test case for performance, to see if we can actually create a game with good looking graphics and gameplay.

     

    @Lumooja: About Havok. I've talked with Steve Ewart from Havok at GDC 2010, and have seen crazy progress and things yet to come. Now that intel is in charge they really have very high goals!

  10. @Lazlo: If Josh wants to use LWE on a wide variety of platform he won't use try-catch error handling (Nintendo ao.).

    @Rick: Buffer* b = new OpenGLBuffer; (without brackets, brackets mean a function. It is valid C++, but not so clean code.)

     

    And I see a lot of assignment overhead...

    Shader* myShader = pFactory->CreateShader();

    (sorry Roland, I just copied it from you because it's on this page :D).

    = a constructor + assignment.

    Shader* myShader(pFactory->CreateShader());

    = only constructor.

     

    I know in most cases you really won't see the difference. But all bits help in game performance...

×
×
  • Create New...