Jump to content

TheoLogic

Members
  • Posts

    142
  • Joined

  • Last visited

Everything posted by TheoLogic

  1. Or use auto if your compiler support this C++11 feature std::vector<Resolution*> ResolutionList; //... for(auto it(ResolutionList.begin()); it != ResultionList.end(); ++it) { /*...*/ }
  2. It is not stupid, and clearly defined in the standard: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf (23.4.4.3 map element access)
  3. There are 2 raknet plugins which may interest your: - http://www.jenkinssoftware.com/raknet/manual/directorydeltatransfer.html - http://www.jenkinssoftware.com/raknet/manual/filelisttransfer.html Never used them, so feedback if you do would be great! If you use C++ on Windows only I propose: http://www.codeproject.com/Articles/7530/Zip-Utils-clean-elegant-simple-C-Win32
  4. TheoLogic

    Relay

    I used Boost on Nintendo Nitro, iOS, OSX, Windows and Android. No problems at all!
  5. TheoLogic

    Relay

    Calling Boost ****, shame yourself! Boost developers are mostly active in the C++ ISO committee and create great libraries which eventually may end up in the standard. Best examples are the new C++11 smart pointers and hash containers. I agree with the fact that you don't want to use Boost, it's pretty cumbersome do yet it deployed, but calling it **** crosses the line.
  6. Agreed, your animation example is a good one. I might state as: * Static: use enumerations * Dynamic: use strings for debug, used hashes in release. You can fairly implement such system that in debug you have access to the actual string value (member of your hash object), but in release it's a hashed version only.
  7. Vector is not a linked list, an element in a vector does not know the next element... Lists are double linked lists. Indeed, maps is probably the most used container after vectors for the reasons you state. I have to agree partially with Josh's comment that you should probably use an "integer type". I suspect he means static const integers, but I would strongly suggest enumerations. Depends, it's rather a design principle. If you don't design your object to be inherited from, just make all members private, else make the members required in the subclass protected. You should never have globals (and if you have them please do add them to a namespace) and public datamembers. Really, a book to read for everyone working with C++! It's "just" 101 rules, short book, but very handy.
  8. You should really read this book: http://www.amazon.co...s/dp/0321113586 Everything you are stating here will gently be countered in 101 rules by Herb Sutter, C++ ISO chairman, and Andrei Alexandrescu. 2 veteran C++ developers! You are burning yourself to the very things they are warning about. For example: 7. Know when and how to code for scalability. 14 10. Minimize global and shared data. 19 11. Hide information. 20 41. Make data members private, except in behaviorless aggregates (C-style structs). 72 76. Use vector by default. Otherwise, choose an appropriate container. 150 77. Use vector and string instead of arrays. 152 78. Use vector (and string::c_str) to exchange data with non-C++ APIs. 153 Really, don't take this the wrong way. I broke myself on endless nights, making the same assumptions as you make. That's just what's making C++ so hard!
  9. Oh boy (going off topic). Iterating over vectors is faster as over a list. List is node based and vector is a contiguous blocks of memory, which the CPU loves... That's also the reason that C# containers are slower as C++ containers, in C# all (except arrays) are node based. And be honest, what do you use the most? Inserting and removing or iterating? * render all items * update all items Simple examples, this is where you need the performance! Not in that rare case where you need to add or remove for example, this could be done during loading! And even most of the time if you require adding, vector push_back is as fast as list push_back. And OK, you have a case where you have both: often iterate and often remove in the middle for example. Use move semantics! Sorry Josh, but you need to work on your C++ skills. * Using std::map (red-black binary tree) for entity management? Use objects, or at least std::unordered_map (C++11 hash map) if you really, really, really want to use an ID * Using std::list where you want std::vector * Public datamembers, just wtf. Encapsulation my friend!
  10. Yep, indeed a C++11 feature. Finally a way to express temporaries! EDIT: Have an article on rvalue references and move semantics for the interested: http://www.benoitroosens.com/articles/rvalue-references-and-move-semantics
  11. Why would that be? Just one example how you can handle it: for(auto it(myVector.begin()); it != myVector.end(); ) { if(must_remove_this_element) { myVector.erase(it++); } else ... } std::vector can reserve capacity, so knowing the maximum number of elements can indeed be a nice thing. However, with move semantics you are able to just move elements on resizing. STL has been modified to support this, so std::vector<std::string> for example will not copy on reallocation, but move. You can write your own move constructor and assignment operator if this is your bottleneck.
  12. First question, do you require a linked-list, or a dynamic array? In my experience, std::vector covers 90% of the container use cases. List: http://www.cplusplus.com/reference/stl/list/ Vector: http://www.cplusplus.com/reference/stl/vector/ Next some remarks on Roland's code: for(auto it(myList.begin()); it != myList.end(); ++it) { cout << *it << endl; } 1. Use auto to define iterator types (if you have a C++11 enable compiler). Saves you time, and you can change the container type as you like and don't break your code. 2. Use '++'-like prefix, especially for iterators. http://thunderguy.com/semicolon/2002/08/13/prefer-prefix-operators-over-postfix/
  13. 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.
  14. 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...
  15. 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!
  16. 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;
  17. 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; ?
  18. 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
  19. I agree with some comments here, VS2008 is not the way to go. For me, the main reason is performance: - Secure_SCL is on by default - No STL in C++11 form (move semantics for example) Both fixed or supported in VS2010. 2 options for the redistributable, static linking or including it in your package.
  20. What are you actually requesting? 1. Actual scene cutscenes, like camera movement, chain of animations, ... 2. Video playing
  21. @ Metatron: can you pls post both compiler arguments for MinGW and VS2010?
  22. TheoLogic

    GetClass

    There is none. What do you want to do?
  23. Fully agree, you must actually know C++ to use the initializer lists. Same applies for static's, inheritance, ... I also agree that you will have redundant code on big classes (one of the reasons to keep them small and simple), that's why "non-static data member initialization" is introduced in C++11. I'm not trying to change your habits. Even though I have a passion for C++, I find myself doing much more C# and python lately . But anyhow, I believe it's a best practice to use the language like it is supposed to. I find myself in the position where I have to maintain legacy C++ code written by COBOL developers, and you won't guess the amount of bugs I found due to uninitialized variables. Before I got here, they've spend 5 months on finding a buffer overflow in old-school C arrays. I refactored the code to use the STL, and it was fixed in 2 hours. Bottom line, initialize your variables, initializer list or not can be a personal preference. I'll quit talking about this, they'll blame the C++ devs of hijacking threads .
  24. Using the language like it is supposed to? You should always initialize your variables, and you now do this in the constructor body yes? If this is the case, why in hell wouldn't you do it in the way the language supports it? I don't see the overhead in initializer list vs constructor body.
  25. How else would you use the initializer list? Not and just putting them in the constructor body? If this is the case, you are loosing performance. You will get a default initialization followed by an assignment! You should always initialize using the initializer list, always, no exceptions. Even if this means nullptr! //h class Foo { public: Foo(); private: int m_whatever; MyObject* m_myObject; }; //cpp Foo::Foo() : m_whatever(0), m_myObject(nullptr) { //Do some stuff so you can actually create m_myObject; m_myObject = ... } This is the same discussion: int blah = 0; //vs int blah(0); Old compilers will not optimize the first one, and you'll get a default construction and an assignment. If you say premature optimization is the root of all evil, I agree. But this is sometimes faster, never slower so I don't consider this as an optimization... But here is the good news, C++11 has a feature called "non-static datamember initialization". Once your compiler is updated, you can do: class Foo { private: int m_whatever = 0; }; But wandering off-topic. Interesting things though
×
×
  • Create New...