22 Apr, 2009, JohnnyStarr wrote in the 1st comment:
Votes: 0
Perhaps someone experienced with C++ can explain C's data structures a bit, that is in comparison
to Objects. I guess the reason I'm asking is because the one the main things I don't like about Diku / Older
C based muds is the inability to use Class Objects. Which raises another question, how dissimilar is a pointer
to structure and an actual object?

ch->name = "Aragorn"
ch.name = "Aragorn"

yes I know this a vague example, but bear with me. the reason I ask is that I don't all together HATE using C and
because most of the snippets out there are for Diku-rivatives I thought if there is a way for me to take my old ROM base
and add some OOP functionality I might save some valuable hours in getting my project underway.

Because of certain limitations of C I started my Ruby project, which for the most part is a ton of fun, but I had worked on my ROM base for about 10 solid months and don't want that to be a waste if can help it.

So for you C++ guys, do you think learning it would avail me to have a more OOP approach? If I'm correct because C++ is s superset of C I can use most of the snippets already out there.
22 Apr, 2009, Grimble wrote in the 2nd comment:
Votes: 0
You can switch to a C++ compiler at any time and compile your ROM base with probably just a few minor tweaks (including snippets).

If your simply planning to treat a class as a data container no different than a structure (as in the example you gave), then there's no point in switching languages. If however, you want to migrate your ROM base to take advantage of what C++ offers beyond C (i.e., abstraction, encapsulation, inheritance, polymorphism, templates, exceptions, etc) then go for it.

Be realistic about it though… re-factoring many thousands of lines of code from a procedural paradigm to an object-oriented paradigm is a significant undertaking, and you'll stay motivated by tackling small pieces at a time. I'd get a road-map established first, so it's clear where you want to go and how you'll get there.
22 Apr, 2009, David Haley wrote in the 3rd comment:
Votes: 0
staryavksy said:
how dissimilar is a pointer to structure and an actual object?

In some ways, they're extremely similar, in others they're completely different, it depends on what you mean. It also depends on what exactly you mean by "an actual object". I'm assuming you mean something that is neither a pointer nor a reference ("on the stack" is what people usually use, although it's not strictly correct).

staryavksy said:
So for you C++ guys, do you think learning it would avail me to have a more OOP approach?

Of course C++ will make it easier to use objects, that is what it was to a large extent designed for. :smile:

Grimble said:
Be realistic about it though…

Grimble's right, don't try to refactor the entire codebase at once. That's tedious, tiring and will likely end in failure (due to abandoning it). It's much better to fix things pieces at a time. A good rule of thumb is that you refactor code as you work on it. For instance, if you find yourself modifying the reset system, it's a good occasion to fix it up.

Unfortunately, in some instances a piece of code affects basically the whole program (think the character structure) so you kind of have to make far-reaching changes. That said, you can still do it little by little. For instance, start by making it a class with a constructor/destructor, but don't make everything private straight away. Leave things as exposed data members initially.
22 Apr, 2009, JohnnyStarr wrote in the 4th comment:
Votes: 0
hmm, i didnt mean to use the word "actual", must have just slipped.

I see where you are coming from. Now that i think of it, besides MERK++ or whatever, are there any full C++ examples out there?
22 Apr, 2009, David Haley wrote in the 5th comment:
Votes: 0
What does "full C++" mean?
22 Apr, 2009, Grimble wrote in the 6th comment:
Votes: 0
I haven't run across any that are as relatively complete as, say, those in the Diku family. But, have a look at…

http://www.andreasen.org/newmud/

…and you'll find at least a few in various stages of completion, with some taking advantage of C++ features more than others.
22 Apr, 2009, JohnnyStarr wrote in the 7th comment:
Votes: 0
Full C++, just meaning that the MERK++ had been altered (if i'm not mistaken) to compile on G++
so that you can ADD C++ features. So once again, my inability to express myself strikes again. :stare:
22 Apr, 2009, David Haley wrote in the 8th comment:
Votes: 0
Well, still, what does that mean? Does it mean that it uses some C++ features? If a few structures have been converted to classes, does that suffice? How about if structures have methods, but don't have the privacy features of classes?

I think what you're trying to ask is whether or not there are codebases that make heavy use of C++ features like classes, maybe overloading, and maybe templates. Is that an accurate description of your question?
22 Apr, 2009, Kayle wrote in the 9th comment:
Votes: 0
David Haley said:
I think what you're trying to ask is whether or not there are codebases that make heavy use of C++ features like classes, maybe overloading, and maybe templates. Is that an accurate description of your question?


If that's what he's looking for AFKMud makes heavy use of C++ features. Also, my own Elysium makes heavy use of them too, but Elysium isn't quite ready for a public debut as of yet.
23 Apr, 2009, Tyche wrote in the 10th comment:
Votes: 0
staryavsky said:
…the reason I ask is that I don't all together HATE using C and
because most of the snippets out there are for Diku-rivatives I thought if there is a way for me to take my old ROM base
and add some OOP functionality I might save some valuable hours in getting my project underway.

Because of certain limitations of C I started my Ruby project, which for the most part is a ton of fun, but I had worked on my ROM base for about 10 solid months and don't want that to be a waste if can help it.


The problem is even if one releases a Ruby or C++ or whatever OOPL server with a complete game, that still ain't going to save you any work. Unless… they recreate the Diku game system. Isn't that what you're really asking for?
23 Apr, 2009, Guest wrote in the 11th comment:
Votes: 0
Kayle said:
David Haley said:
I think what you're trying to ask is whether or not there are codebases that make heavy use of C++ features like classes, maybe overloading, and maybe templates. Is that an accurate description of your question?


If that's what he's looking for AFKMud makes heavy use of C++ features. Also, my own Elysium makes heavy use of them too, but Elysium isn't quite ready for a public debut as of yet.


Not that I'd promote using AFKMud as a shining example of the right way to do things. But yes, it does make use of a number of C++ thingies :)
23 Apr, 2009, elanthis wrote in the 12th comment:
Votes: 0
staryavsky said:
Perhaps someone experienced with C++ can explain C's data structures a bit, that is in comparison
to Objects.


C's structures are conceptually just convenient collections of variables in a reusable definition.

Quote
Which raises another question, how dissimilar is a pointer to structure and an actual object?


That really depends. At a very low level, a C++ class is just a C struct. In fact, in C++, you can add base classes, methods, static variables, and so on to a struct. The keyword 'class' is really just a synonym for 'struct' in C++ with one small difference: the access mode for struct is public by default but it's private by default for class. That's it.

A pointer to a struct and a pointer to an object are thus identical. They are just pointers to regions in memory that have variables in some particular layout as defined by the struct/class. Likewise, a stack-allocated struct and a stack-allocated class are essentially identical.

That said, C++ will add hidden members to a class (or struct) when you use virtual methods, or when you derive from a type with virtual members. That, these will create identical in-memory representations and (if you cast between them) are interchangeable:

struct foo_struct {
int foo;
double bar;
};

class foo_class {
int foo;
double bar;

// add in a constructor to show that this is a "real class"
foo_class (int _foo, double_bar) : foo(_foor), bar(_bar) {}

// and a method
double mul() { return foo * bar; }
};


However, the above struct is NOT identical internally to the following class, and if you cast between them, things will break!

class foo_class {
int foo;
double bar;

// add in a constructor to show that this is a "real class"
foo_class (int _foo, double_bar) : foo(_foor), bar(_bar) {}

// and a method
virtual double mul() { return foo * bar; }
};


The reason is that the second class has a virtual method. In order to implement virtual methods, C++ adds a hidden pointer member into the underlying memory layout for the class that is used to look up the specific definition of foo_class::mul to invoke when the virtual function is called.

That is all a technical explanation, of course. Practically, a struct is just another way to say class, and two different classes – even if they have the same members – are not compatible.

Quote
ch->name = "Aragorn"
ch.name = "Aragorn"


This is just an artifact of the relatively goofy grammar of C (and hence C++). You use -> if the left-hand side is a pointer and you use . if it's not (that is, if its a local variable or a class member). It really has no semantic purpose whatsoever, and the original C designers could have with a little effort just made the grammar use one or the other for both circumstances… but they didn't.

On a more technical level to help understand the difference from other OOP languages, C/C++ allows you to allocate variables in one of two places: on the stack or in the heap. The stack is where local variables are defined. Such variables dsiappear when the current scope (e.g. function, loop, etc.) ends. Heap-allocated variables only disappear when you tell them to.

Pointers and non-pointers can also be thought of as the difference between a reference (which means something else in C++, just to be more confusing) and a copy. In many OOP languages, if b is an object, then a = b just means "a now references the same object that b does." In C/C++, however, if b is a struct or class (not a pointer to) then a= b means "copy the data from b into a." If you want a reference, you need to use a pointer (iin C) or either a pointer or a reference-type (in C++).

The C++ reference type is a weird little creature that mostly exists to work around other language features. It creates a reference that acts like a regular variable. Explaining them in detail is beyond my capabilities if you want it to stay shorter than a whole chapter. :/

In general, though, use -> for anything that's a pointer and use . for anything that isn't, and don't worry too much about why because it's just a design artifact.

Quote
Because of certain limitations of C I started my Ruby project, which for the most part is a ton of fun, but I had worked on my ROM base for about 10 solid months and don't want that to be a waste if can help it.


Continuning work on a codebase you don't like is far more of a waste than the initial work itself. If you don't care for the ROM code, don't work on it anymore. Don't think of it as a waste, think of it as a valuable learning experience.

Quote
So for you C++ guys, do you think learning it would avail me to have a more OOP approach?


C++ is really crappy OOP, honestly. The C++ designer took the true OO concepts and then married them to the very low-level bare-metal C language. This has many advantages if you actually need that low-level support, but if you're writing a regular application, there's no reason to saddle yourself with C++'s many limitations. Ruby does everything C++ does and more.

Quote
If I'm correct because C++ is s superset of C I can use most of the snippets already out there.


Yes and no. Snippets (god I hate that word) are less about the language and more about the specific codebase. A ROM snippet will not even remotely come class to being even slightly useful to someone using Source MUD, for example. If you modify a ROM MUD enough (like converting it to C++) then you really end up with some kind of ROM derivative, and available snippets will become very hard to use.

You're better off avoiding most snippets anyway as anything besides a learning exercise: most are pure crap.
23 Apr, 2009, Grimble wrote in the 13th comment:
Votes: 0
elanthis said:
The C++ reference type is a weird little creature that mostly exists to work around other language features. It creates a reference that acts like a regular variable. Explaining them in detail is beyond my capabilities if you want it to stay shorter than a whole chapter. :/
In general, though, use -> for anything that's a pointer and use . for anything that isn't, and don't worry too much about why because it's just a design artifact.

References can't be created NULL, so they can buy you some safety from NULL pointers. But if you're going down the C++ path, there are few cases for using raw pointers anyway. Use strong and weak pointers from the Loki or Boost libraries, soon to be standardized into the language.

elanthis said:
C++ is really crappy OOP, honestly. The C++ designer took the true OO concepts and then married them to the very low-level bare-metal C language. This has many advantages if you actually need that low-level support, but if you're writing a regular application, there's no reason to saddle yourself with C++'s many limitations. Ruby does everything C++ does and more.

Broad and vague statements like this do nothing to support whatever point you're trying to make. What is crappy about it? What limitations are you referring to? What does Ruby do better? Surely not everything?
23 Apr, 2009, Kline wrote in the 14th comment:
Votes: 0
Along the lines of C++: is there any smart way to cast void pointers to something else? Akin to having a list of void pointers that could point to any number of different data types, and relying on whatever function accesses the list to cast and read the pointer appropriately? Like would this be a case for a template function? I'm not sure where to head with it as it works wonderfully to just cast them in C, but newer G++ versions aren't liking that solution :)
24 Apr, 2009, Davion wrote in the 15th comment:
Votes: 0
When I want to accomplish this, I usually use the static_cast operator
24 Apr, 2009, Kline wrote in the 16th comment:
Votes: 0
I've tried static casting, and that gives me errors, maybe this example of exactly what I'm trying to do will help. I have one of the old Diku-based hash functions that returns a void pointer:
void *get_hash_entry( hash_table * hash_head, int key )

I tried this with no success:
static_cast<int>( get_hash_entry(arg1,arg2) )

The resulting error is this:
invalid static_cast from type 'void*' to type 'int'


Am I missing something? I've got other static_casts in use elsewhere without problems, but going from a void pointer…Not working.
24 Apr, 2009, ghasatta wrote in the 17th comment:
Votes: 0
You can't cast from a pointer to a non-pointer. Try:
static_cast<int *>(…)
24 Apr, 2009, Kline wrote in the 18th comment:
Votes: 0
I tried that route too, just out of curiosity:
error: invalid conversion from 'int*' to 'int'
24 Apr, 2009, Grimble wrote in the 19th comment:
Votes: 0
Kline said:
I tried that route too, just out of curiosity:
error: invalid conversion from 'int*' to 'int'

After you re-cast void* to int*, what is the type of the variable you are copying it into (i.e., what's on the left hand side of the static_cast<> operation)? I'm guessing it's a plain old int. You could consider re-factoring the hash table code to use boost::any instead of void*.
24 Apr, 2009, Kline wrote in the 20th comment:
Votes: 0
Yeah, it is a plain old int that I'm trying to push data into. I looked at some of the boost stuff before, for other reasons, and while it would make things immensely easier on me, I really don't want to rely on external libraries to help keep things portable for others to use :(.
0.0/32