Roland Posted June 24, 2010 Share Posted June 24, 2010 I agree on the concept of Object myObject = new Object1(); instead of object = CreateObject(). It is a personal choice though: New programmers will probably like the CreateObject() command because it is a slightly more obvious command. More experienced programmers will like the resemblance with the C# like structure. The main difference is that when creating the object using a Create method you can always have objects as members of another class and don't have to use the new command. When having the creation in the constructor (along with argument) you have to have the object as a member pointer in a class and the use new Object to create it, and of course delete object in the destructor. Personally I have no problems with this, but some folks seems to be scared about using new. The reasons for be afraid of new and pointer are to me a bit irrational, but I have noticed that this phenomena exists. I would personally go for the creation in the constructor, but I can understand that some finds the Create method to create feels better. There are though some problems with having a Create method. Here is a little code snippet from a test program of my Cells GUI that shows this. GuiImage* pgui = new GuiImage( (GraphicsWidth()-800)/2, (GraphicsHeight()-600)/2, "abstract::goback_n", GuiAll ) ; pgui->AddChild( new GuiButton( 10, 10, "abstract::a", GuiAll, "A", &click ) ) ; pgui->AddChild( new GuiButton( 266, 10, "abstract::b", GuiAll, "B", &click ) ) ; pgui->AddChild( new GuiButton( 10, 266, "abstract::c", GuiAll, "C", &click ) ) ; As you can see I use the creation by constructor as this I the way I prefer. In this example adding new childs is quite simple by adding them with new. Now if the construction of GuiButtons would have been done by using a Create methods it would now have been quite so smooth. I show this alternative here below. GuiImage gui; gui.Create( (GraphicsWidth()-800)/2, (GraphicsHeight()-600)/2, "abstract::goback_n", GuiAll ) ; GuiButton b1( ) ; b1.Create( 10, 10, "abstract::a", GuiAll, "A", &click); gui.AddChild( b1 ); GuiButton b2( ) ; b2.Create( 266, 10, "abstract::b", GuiAll, "B", &click) ; gui.AddChild( b2 ); GuiButton b3( ) ; b3.Create( 10, 266, "abstract::c", GuiAll, "C", &click ) ; gui.AddChild( b3 ); // note: b1, b2, b3 must bee stored somewhere as they will // cause null-references if they go out of scope I think the samples above shows the advantage of using new instead of Create. But as Aggror says. Its a matter of taste in the end. You get the same result both ways, but using a different approach. Quote Roland Strålberg Website: https://rstralberg.com Link to comment Share on other sites More sharing options...
Canardia Posted June 24, 2010 Share Posted June 24, 2010 You can do it even easier, like I did in my GUI: GUI gui; gui.AddWindow("About"); gui.AddButton("About","OK"); Then you can check if the button was pressed: if( gui.ButtonClicked("About","OK") ) { } Quote ■ Ryzen 9 ■ RX 6800M ■ 16GB ■ XF8 ■ Windows 11 ■ ■ Ultra ■ LE 2.5 ■ 3DWS 5.6 ■ Reaper ■ C/C++ ■ C# ■ Fortran 2008 ■ Story ■ ■ Homepage: https://canardia.com ■ Link to comment Share on other sites More sharing options...
Roland Posted June 24, 2010 Share Posted June 24, 2010 You can do it even easier, like I did in my GUI: GUI gui; gui.AddWindow("About"); gui.AddButton("About","OK"); Then you can check if the button was pressed: if( gui.ButtonClicked("About","OK") ) { } There are many ways to do a GUI. But thats out of topic here. The idea was just to show the difference between using new and Create, not to discuss Gui's specifically. That belongs to another thread. Quote Roland Strålberg Website: https://rstralberg.com Link to comment Share on other sites More sharing options...
Canardia Posted June 24, 2010 Share Posted June 24, 2010 Yes, but I showed also that new and Create() is both not needed. I just use a STL map and set values into it. You can do the same for any objects: worldmap["cube1"]=Cube; // Cube class has constructor which creates it, and then // deletes after the map has got it worldmap["oildrum1"]=LoadModel("oildrum.gmf"); Quote ■ Ryzen 9 ■ RX 6800M ■ 16GB ■ XF8 ■ Windows 11 ■ ■ Ultra ■ LE 2.5 ■ 3DWS 5.6 ■ Reaper ■ C/C++ ■ C# ■ Fortran 2008 ■ Story ■ ■ Homepage: https://canardia.com ■ Link to comment Share on other sites More sharing options...
Roland Posted June 24, 2010 Share Posted June 24, 2010 Yes, but I showed also that new and Create() is both not needed. I just use a STL map and set values into it. Ok. But thats has nothing to do with new or Create Quote Roland Strålberg Website: https://rstralberg.com Link to comment Share on other sites More sharing options...
Canardia Posted June 24, 2010 Share Posted June 24, 2010 Internally STL map uses also new, but the user doesn't have to know it, and to deal with ugly forgotten delete instructions, plus setting the pointer manually to NULL after that. You could use STL containers for all variables, then you have also the possibility to loop through all your variables, and to lookup them. It would allow you to save/load the program state from disk also. Having all objects randomly spread out through the code without any kind of control when they are created and deleted, is not so good. Quote ■ Ryzen 9 ■ RX 6800M ■ 16GB ■ XF8 ■ Windows 11 ■ ■ Ultra ■ LE 2.5 ■ 3DWS 5.6 ■ Reaper ■ C/C++ ■ C# ■ Fortran 2008 ■ Story ■ ■ Homepage: https://canardia.com ■ Link to comment Share on other sites More sharing options...
Roland Posted June 24, 2010 Share Posted June 24, 2010 Internally STL map uses also new, but the user doesn't have to know it, and to deal with ugly forgotten delete instructions, plus setting the pointer manually to NULL after that. You could use STL containers for all variables, then you have also the possibility to loop through all your variables, and to lookup them. It would allow you to save/load the program state from disk also. Having all objects randomly spread out through the code without any kind of control when they are created and deleted, is not so good. Who has said anything about not using containers. Still. Using containers has absolutely nothing to do with new or Create. Its up to me, the user of a container to decide the content of the container, it can be objects, pointers, integers, booleans or whatever. Hence this is also a container std::vector<Object*> container ; container.push_back( new Object() ) ; Again. The usage of containers has nothing to do with new or Create. About having object randomly spread out through the code etc.... This statement has nothing to do with the subject either. You are then discussing design of a program and nothing else. Then about using new in constructors. Thats a common practice and is totally safe to do if you place delete in the destructor. Cant be that hard to remember. New is constructor -> delete in destructor. Edit: Lumooja... admit you are happy that I'm back Quote Roland Strålberg Website: https://rstralberg.com Link to comment Share on other sites More sharing options...
paramecij Posted June 25, 2010 Share Posted June 25, 2010 (edited) what's wrong with CreateObject()? I'm an experienced programmer and appreciate it's procedural C like design. I was a big OO guy long ago, excited about C#.., but in game development I sooner or later always had to break OO rules or general good coding principles, or wished to use some other library which wasn't OO.(C is like the least common denominator for other platforms & libraries + I can write the fastest code there). I can code in pretty much any language & style, but I found procedural C mixed with OO code where it's benefiting, to be optimal for me. With LE it's easy to make quick hacked-in prototypes or isolated functionality tests (esp. with Bmax) which I can later re-factor into my main code base. I hope this will be true for 3.0 also! ..but back on the topic of documentation, we decided (or rather Josh did) to feature freeze the engine until it's bug free, ..what if we "design" freeze the documentation until it's complete and 1:1 with the current engine version. Then paste it into a database and feed it through the new design? And let Aggror work in peace & quiet -edit: Wow i missed the whole 6th page @Roland I thought we were talking about CreateObject() as in CreateCube(), LoadModel() etc. ..Maybe i'm missing the whole point, it's 4AM here Edited June 25, 2010 by paramecij Quote Link to comment Share on other sites More sharing options...
Josh Posted June 25, 2010 Author Share Posted June 25, 2010 I think it's a good idea to have CreateMesh(), etc., only for the purpose of filling in the C command set. I don't actually expect anyone to code in pure C. The purpose of the C syntax is actually to provide a consistent command set that every programming language can access. For C++ I expect programmers to use new, and all tutorials and documentation will reflect this. Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Pixel Perfect Posted June 25, 2010 Share Posted June 25, 2010 The purpose of the C syntax is actually to provide a consistent command set that every programming language can access. For C++ I expect programmers to use new, and all tutorials and documentation will reflect this. Sounds eminently sensible to me Quote Intel Core i5 2.66 GHz, Asus P7P55D, 8Gb DDR3 RAM, GTX460 1Gb DDR5, Windows 7 (x64), LE Editor, GMax, 3DWS, UU3D Pro, Texture Maker Pro, Shader Map Pro. Development language: C/C++ Link to comment Share on other sites More sharing options...
Canardia Posted June 25, 2010 Share Posted June 25, 2010 I'm never going to use new since it breaks the dot notation of OOP, and I want cross-language compatible code, so I can copy paste from C++ to BlitzMax, Lua, and other OOP languages. Besides, other engines use Create() too, so it's also slowly getting an industrial standard. Even if the tutorials use new, I can still use scope allocations: Tutorial: Mesh* cube=new Cube(); Vec3* v=new Vec3(0,0,1); cube->Move(v); delete v; delete cube; My Way: Mesh cube; cube.Move(Vec3(0,0,1)); The only difficulty in My Way when LE is using new notation, is to create global objects, but it can be done with deferred instancing: map<string,World> world; map<string,Mesh> mesh; void deferred_init(void) { World world; world["main"]=world; Cube cube; mesh["cube"]=cube; } int main() { deferred_init(); mesh["cube"].Move(Vec3(0,0,1)); } And I can even use references to make it faster than with pointers: int main() { deferred_init(); Cube& cube=mesh["cube"]; cube.Move(Vec3(0,0,1)); } So actually this is a cool new way to do things, since you don't need to call a slow ForEachEntityDo() anymore, but can access directly each entity by name, without any looping and finding. Quote ■ Ryzen 9 ■ RX 6800M ■ 16GB ■ XF8 ■ Windows 11 ■ ■ Ultra ■ LE 2.5 ■ 3DWS 5.6 ■ Reaper ■ C/C++ ■ C# ■ Fortran 2008 ■ Story ■ ■ Homepage: https://canardia.com ■ Link to comment Share on other sites More sharing options...
Roland Posted June 25, 2010 Share Posted June 25, 2010 @Roland I thought we were talking about CreateObject() as in CreateCube(), LoadModel() etc. ..Maybe i'm missing the whole point, it's 4AM here I was talking about LEO which is wrapping those into classes. Cube c ; c.Create(...) ; is equivalent to TEntinty c ; c = CreateCube(...) So its actually the same thing in two different approaches Quote Roland Strålberg Website: https://rstralberg.com Link to comment Share on other sites More sharing options...
Roland Posted June 25, 2010 Share Posted June 25, 2010 I'm never going to use new since it breaks the dot notation of OOP, and I want cross-language compatible code, so I can copy paste from C++ to BlitzMax, Lua, and other OOP languages. Besides, other engines use Create() too, so it's also slowly getting an industrial standard. Even if the tutorials use new, I can still use scope allocations: Tutorial: Mesh* cube=new Cube(); Vec3* v=new Vec3(0,0,1); cube->Move(v); delete v; delete cube; My Way: Mesh cube; cube.Move(Vec3(0,0,1)); The only difficulty in My Way when LE is using new notation, is to create global objects, but it can be done with deferred instancing: map<string,World> world; map<string,Mesh> mesh; void deferred_init(void) { World world; world["main"]=world; Cube cube; mesh["cube"]=cube; } int main() { deferred_init(); mesh["cube"].Move(Vec3(0,0,1)); } My way: Mesh cube = Cube( Vec3(0,0,1) ) ; ... ... some code ... or Mesh* pcube = new Cube( Vec3(0,0,1) ) ; ... ... some code ... delete pcube ; Quote Roland Strålberg Website: https://rstralberg.com Link to comment Share on other sites More sharing options...
Canardia Posted June 25, 2010 Share Posted June 25, 2010 My way: Mesh cube = Cube( Vec3(0,0,1) ) ; ... ... some code ... You are calling Mesh destructor twice, since Mesh is a base class of Cube. It should be: Mesh& cube = Cube(Vec3(0,0,1)); I tested it with this code: #include <iostream> using namespace std; class Mesh { public: Mesh(){cout<<"mesh initialized"<<endl;} virtual ~Mesh(){cout<<"mesh uninitialized"<<endl;} }; class Cube : public Mesh { public: Cube(){cout<<"cube shape created"<<endl;} virtual ~Cube(){cout<<"cube shape destroyed"<<endl;} }; int main() { Mesh& cube = Cube(); } Quote ■ Ryzen 9 ■ RX 6800M ■ 16GB ■ XF8 ■ Windows 11 ■ ■ Ultra ■ LE 2.5 ■ 3DWS 5.6 ■ Reaper ■ C/C++ ■ C# ■ Fortran 2008 ■ Story ■ ■ Homepage: https://canardia.com ■ Link to comment Share on other sites More sharing options...
Roland Posted June 25, 2010 Share Posted June 25, 2010 You are calling Mesh destructor twice, since Mesh is a base class of Cube. It should be: Mesh& cube = Cube(Vec3(0,0,1)); I tested it with this code: #include <iostream> using namespace std; class Mesh { public: Mesh(){cout<<"mesh initialized"<<endl;} virtual ~Mesh(){cout<<"mesh uninitialized"<<endl;} }; class Cube : public Mesh { public: Cube(){cout<<"cube shape created"<<endl;} virtual ~Cube(){cout<<"cube shape destroyed"<<endl;} }; int main() { Mesh& cube = Cube(); } Yes. Your are right. However. This discussion is now so off topic as it could be. If we should continue the "to new or not to new" discussion it must be in a separate thread. Although I don't think there is any point in doing that. You have your view and I have mine and thats perfectly OK. Quote Roland Strålberg Website: https://rstralberg.com Link to comment Share on other sites More sharing options...
Canardia Posted June 25, 2010 Share Posted June 25, 2010 But this whole thread IS about new or not to new. It says in the title "Documentation", and the documentation will need to use either new, reference (same as new, just modern way to do it), or the old Create() style: I think it's a good idea to have CreateMesh(), etc., only for the purpose of filling in the C command set. I don't actually expect anyone to code in pure C. The purpose of the C syntax is actually to provide a consistent command set that every programming language can access. For C++ I expect programmers to use new, and all tutorials and documentation will reflect this. So I suppose we are discussing now the content of the documentation, since the documentation site has been already done with custom mysql database. Quote ■ Ryzen 9 ■ RX 6800M ■ 16GB ■ XF8 ■ Windows 11 ■ ■ Ultra ■ LE 2.5 ■ 3DWS 5.6 ■ Reaper ■ C/C++ ■ C# ■ Fortran 2008 ■ Story ■ ■ Homepage: https://canardia.com ■ Link to comment Share on other sites More sharing options...
Roland Posted June 25, 2010 Share Posted June 25, 2010 But this whole thread IS about new or not to new. It says in the title "Documentation", and the documentation will need to use either new, reference (same as new, just modern way to do it), or the old Create() style: So I suppose we are discussing now the content of the documentation, since the documentation site has been already done with custom mysql database. As Shakespeare would have put it "To new or not to new. That is the question" You might be right. Quote Roland Strålberg Website: https://rstralberg.com Link to comment Share on other sites More sharing options...
Josh Posted June 25, 2010 Author Share Posted June 25, 2010 It's relevant because the API design interacts with the design of the documentation system, and the documentation system is being designed with future scalability in mind. I'm never going to use new since it breaks the dot notation of OOP, and I want cross-language compatible code, so I can copy paste from C++ to BlitzMax, Lua, and other OOP languages. Exactly. The purpose of the C command set is not necessarily to program in C (although I know you like it). The C command set is the general command set that is not tied to any single language. Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Canardia Posted June 25, 2010 Share Posted June 25, 2010 Exactly. The purpose of the C command set is not necessarily to program in C (although I know you like it). The C command set is the general command set that is not tied to any single language.Yes, the C notation has been always cross-language compatible. And it's possible to make the C++/OOP notation also cross-language compatible by using references instead of pointers. It doesn't change anything in the engine though, it's just a different way how the user can use LE. But this is actually cool, since now both old skool C++ programmers: ClassName* object = new ClassName(); object->Method(); and new skool C++ programmers: ClassName& object = ClassName(); object.Method(); and ClassName object; object.Method(); can use it. The documentation can use either syntax, although I would prefer the latter style, since I think it looks ugly to use "->" instead of ".", besides it's more to type Quote ■ Ryzen 9 ■ RX 6800M ■ 16GB ■ XF8 ■ Windows 11 ■ ■ Ultra ■ LE 2.5 ■ 3DWS 5.6 ■ Reaper ■ C/C++ ■ C# ■ Fortran 2008 ■ Story ■ ■ Homepage: https://canardia.com ■ Link to comment Share on other sites More sharing options...
Rick Posted June 25, 2010 Share Posted June 25, 2010 I think it's a good idea to have CreateMesh(), etc., only for the purpose of filling in the C command set. I don't actually expect anyone to code in pure C. The purpose of the C syntax is actually to provide a consistent command set that every programming language can access. For C++ I expect programmers to use new, and all tutorials and documentation will reflect this. So 3.0 will be in C++ and object oriented, but then you plan on creating a C wrapper to that? Not that it really matters but that's almost backwards form anything I've seen. Normally you see C++ OO wrappers to C code. Quote Link to comment Share on other sites More sharing options...
Canardia Posted June 25, 2010 Share Posted June 25, 2010 I think the C wrapper serves only as reference how to implement the DLL interface for other languages, and is not really meant to be used directly. From that reference, people can then make OOP or procedural headers for other languages. Quote ■ Ryzen 9 ■ RX 6800M ■ 16GB ■ XF8 ■ Windows 11 ■ ■ Ultra ■ LE 2.5 ■ 3DWS 5.6 ■ Reaper ■ C/C++ ■ C# ■ Fortran 2008 ■ Story ■ ■ Homepage: https://canardia.com ■ Link to comment Share on other sites More sharing options...
macklebee Posted June 26, 2010 Share Posted June 26, 2010 agree... and personally don't think OOP should be forced upon anyone... if someone wants OOP then they need to have a OOP wrapper. The base code should be procedural for all languages. Quote Win7 64bit / Intel i7-2600 CPU @ 3.9 GHz / 16 GB DDR3 / NVIDIA GeForce GTX 590 LE / 3DWS / BMX / Hexagon macklebee's channel Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.