15 May, 2009, David Haley wrote in the 21st comment:
Votes: 0
I'm not talking about "interface" in the Java/C# sense, which is only a definition of a set of public methods, typically without implementation. By "interface", I mean the way in which you talk to (i.e., manipulate) an object. It's a general programming concept that applies even without OOP, e.g., the interface to a module (its public API).

So it's not necessarily bad form to say player.level++, it depends on the design. In languages like C++, you can define member visibility, and actually prevent people outside the class from being able to muck around with so-called private fields. In C, you can't prevent this. So let's say that you have something like this:

void level_up(Character* ch) {
if (ch->level >= 50) {
return;
}
else {
ch->level++;
}
}


and you make it clear (in .h files, comments, whatever) that the interface to ch->level is via the level_up function. (This is contrived, but whatever.) If somebody then goes in and manually increments ch->level, they can violate the constraint imposed by the function, namely that level does not go above 50.

Here's a much more interesting example. Characters have equipped object lists – objects that are currently in use by the character. There is a very clear interface to equipment: you are supposed to use the equip/unequip functions. These functions take care of an awful lot of housekeeping, like effects, armor class, and so forth.
The consequences of bypassing this interface can be pretty bad, like not actually applying effects, or applying them but then not removing them when you unequip, etc.
Not following the interface means manually adding things into the equipment linked list.

Basically that is what I mean by "respecting the interface" – there is a clear set of functions you are supposed to use for certain state manipulations. C allows you to bypass that interface by directly editing the structure data members, which is a Very Bad Thing to do. C++ makes it much harder to bypass the interface because you can't access the data members directly.
15 May, 2009, KaVir wrote in the 22nd comment:
Votes: 0
staryavsky said:
I'm curious what a C++ MUD would look like if done correctly. It's kind of weird that for all the muds that are out there, there are none that i can find that are in C++ that are written with a good object oriented structure.

C++ is a general-purpose multi-paradigm programming language. One of its biggest strengths is that there isn't one "correct" way of developing software with it. I suspect most hardcode OO programmers are using different languages.

David Haley said:
Basically that is what I mean by "respecting the interface" – there is a clear set of functions you are supposed to use for certain state manipulations. C allows you to bypass that interface by directly editing the structure data members, which is a Very Bad Thing to do. C++ makes it much harder to bypass the interface because you can't access the data members directly.

It's perfectly possible to write C++ code and leave all of the member variables public. It's also perfectly possible to write C code where the variables have local (file) scope and can only be accessed externally via functions defined in the header. As you said earlier, Object Oriented techniques can be appied in any language, it's just that some make it easier than others.
15 May, 2009, David Haley wrote in the 23rd comment:
Votes: 0
KaVir said:
It's perfectly possible to write C++ code and leave all of the member variables public.

Well, it's also possible to shoot yourself in the foot, but, eh, I was assuming we were talking about good applications of concepts here. :tongue:

KaVir said:
It's also perfectly possible to write C code where the variables have local (file) scope and can only be accessed externally via functions defined in the header.

Ah, well, yes, until you want to instantiate several copies of your objects… As soon as somebody gets a pointer to a structure, they can start screwing with it.

For clarity's sake, I'm not interested in ways one could obfuscate one's way around problems by introducing contortions that make programming harder than it already is. Yes yes, you can always put in all kinds of tricks; the point here is not to use tricks to make life more difficult, it is to use tricks to make life easier…
16 May, 2009, KaVir wrote in the 24th comment:
Votes: 0
David Haley said:
Well, it's also possible to shoot yourself in the foot, but, eh, I was assuming we were talking about good applications of concepts here.

You were talking about a good application of encapulation in C++ and a bad application in C. I don't think that's a very useful comparison. C++ makes this sort of thing easier, but it's certainly possible to come up with both good and bad solutions in either language.

KaVir said:
Ah, well, yes, until you want to instantiate several copies of your objects… As soon as somebody gets a pointer to a structure, they can start screwing with it.

There are ways to around that as well, just as there are ways for a determined programmer to view and manipulate the private data of your C++ objects if they really to.
16 May, 2009, elanthis wrote in the 25th comment:
Votes: 0
David Haley said:
I don't have the link around, but I read that several people have tried to redesign C++ but wanting to do it "correctly", while respecting the initial design goals. It turns out that it's extremely difficult to make a new language that respects C++'s goals without ending up with pretty much exactly C++ all over again. (The goals being things like C programs should also be C++ programs, there should be no cost if you don't use C++ features, etc.)


Yeah, you really can't do better than C++ for what it was intended to do. You can do a lot better than C++ if you eschew a few of those goals (e.g. C syntax compatibility). In fact, if you get rid of that one particular feature of C++, you pretty much end up with D. Which isn't a bad language at all – the only thing stopping me from really using it is the horrifically designed and bloated standard library. (Sadly, the D stdlib redesign project is equally stupid and bloated. ::sigh::) The ironic part is that I'm pretty sure D only tries to include a Java-sized stdlib because it lacks C compatibility and so you need a ton of standard library features to make up for the lack of existing usable libraries.

Quote
Ah, well, yes, until you want to instantiate several copies of your objects… As soon as somebody gets a pointer to a structure, they can start screwing with it.


As KaVir implied, you can screw with anything. All of your C/C++ code can access any memory used by any other part of your application. Unless you're working with a managed, verified language, that's always true.

That said, even in C you can make private members. Just don't actually define a struct in any header file. You can pass around pointers to undefined structs in C so you can still get C type checking without ever exposing the internal details of a struct. If you need a mix of public/private data, you can use similar tricks. Define a public struct but in the internal code use an extended struct. The only restriction any of this imposes is that you can't allocate the struct in user code, so you have to provide at the very least a struct mystruct* mystruct_new(void), which makes sense anyway since you probably want to initialize all those private members.

One neat thing that this trick in C does that C++ is not is remove the need to update a public header file if you want to add/remove fields, which means that you can make certain implementation changes without having to recompile half your app. Kind of nice for large apps, although C compilation times are usually far smaller than C++ times anyway (no template instantiation… which btw is another reason C++0x is going to be nice, thanks to extern templates, which g++ already supports).
16 May, 2009, JohnnyStarr wrote in the 26th comment:
Votes: 0
KaVir said:
C++ is a general-purpose multi-paradigm programming language. One of its biggest strengths is that there isn't one "correct" way of developing software with it. I suspect most hardcode OO programmers are using different languages.

If you would have read the beginning of the thread you would see that by 'correct way' of writing code, I was not considering the opinions of every developer or every style or even every paradigm that exists. It was in scope with the thread, in which I believe David pointed out that there are flat out wrong ways of doing things, but there are also things by most to be considered backwards or inefficient ways. So therefore, in light of the thread 'incorrect'.

In other words, I know there are multiple ways to implement good code, but I am interested only in posts that are constructive and that don't lose sight of the principles behind the advice given.
16 May, 2009, KaVir wrote in the 27th comment:
Votes: 0
staryavsky said:
If you would have read the beginning of the thread you would see that by 'correct way' of writing code, I was not considering the opinions of every developer or every style or even every paradigm that exists.

Your earlier posts were just a bunch of questions about basic programming concepts. My post was in response to your later statement (which I also quoted in my reply):

staryavsky said:
I'm curious what a C++ MUD would look like if done correctly. It's kind of weird that for all the muds that are out there, there are none that i can find that are in C++ that are written with a good object oriented structure.

You seem to be suggesting that an object-oriented approach is the "correct" way to write a program in C++. It isn't. It's just one of the approaches that C++ supports.
16 May, 2009, elanthis wrote in the 28th comment:
Votes: 0
Stary, KaVir wasn't being unconstructive at all. In fact, you should pay close attention to anything he says: man knows what he's talking about. His point is that you asked for an example of a "C++ MUD that has good OO structure" but that question is pretty much the same asking to see a "tomato that has good cooking potential." ;) Basically, you should ask to see a well written C++ MUD, and not just for one that represents good OO programming.

In particular, no C++ MUD is really going to be a paradigm of OO-ness, because if it was it would be a crappy C++ application as a whole. One of C++'s biggest strengths is that you can use OO where it makes sense and avoid it entirely where it doesn't. C++ code that makes excessive use of objects and OO end up being hard to read and hard to grok, a lot like how Java or C# apps can end up being overly complicated because you have to create a new class or object for -everything-, except that unlike Java or C#, creating new classes and objects is relatively painful in C++. Good OO and C++ aren't really compatible concepts, because C++ is a horrible OOP language compared to even the state of the art at the time C++ was conceived.

To sort of answer your question: Source MUD is C++. I do not at all think of it as a paradigm of good C++ strategy, as it's been built up over the years starting from when I was 16 and that shows… badly. It does use a lot of object orientation for the game entities, session handling, and commands, which may be what you were looking for. A lot of the code is a mess though, so be warned. The code is also still undergoing heavy changes as I try to make it not suck and make it represent Good Code, so it's in even more of a mess than it otherwise would be; a lot of features are currently disabled or broken and it may not even compile or run at all right now.
16 May, 2009, JohnnyStarr wrote in the 29th comment:
Votes: 0
Ok, that makes sense.
I'm willing to admit I may have been hasty in my rebuttal,
for what its worth I've observed on several forums that sometimes
people can be more focused on trying to sound smart by adding unneeded
complication to a simple question that most of times was not asked properly (by this I refer to 90% of my questions). So I wasn't implying that KaVir didn't know his stuff, but at the time it seemed irrelevant.

It might be noted that I'm used to having my questions answered by David Hailey, and as frustrating as it must be to answer my questions, he seems already to understand most of what I'm asking without reading into it.

So anyway, thanks for your input, no offense intended.
16 May, 2009, JohnnyStarr wrote in the 30th comment:
Votes: 0
Thanks also elanthis,
I appreciate that you looked past the actual words i used and saw the point i was trying to make. I see what you mean about C++ not being totally OO. I'll be more careful how i word things.
16 May, 2009, David Haley wrote in the 31st comment:
Votes: 0
Just to be clear, my point was not that it's impossible to edit private fields – it is of course possible, and yes, it's also possible to emulate private fields in C. (The pointer to an undefined impl struct is one of the more common tricks. It also makes inheritance a little easier to manage.) My point was to show how language features can be more or less conducive to more or less bad programming, unless you are careful. It's like how in Perl, it's perfectly possible to write decent code, you just have to put more effort and care into it because the language encourages a certain style. So, the idea is to discuss not what is possible strictly speaking by going through contortions (of varying degrees, of course), but what is easy, convenient, straightforward, and so forth.

Anyhow, I think this particular point is probably about done by now… so moving on. :smile:

Stary, IMO I think that learning to speak precisely is valuable not only for communicating to others what you mean, but also for organizing your own thoughts. This is certainly true in my case at least; when I first started writing C and C++, I didn't really know or understand the concepts, and couldn't talk about things precisely – which implied that I also couldn't think about things precisely. This tended to manifest itself in my code in the form of sloppy or simply strange design, or in things simply not working or not being able to grow beyond a certain point. (One of my early frustrations was being able to get things started but then discover that the code was not scalable to a more complete system.) I imagine that Elanthis is referring to something similar in that code written while young (in one's programming career) can really stink quite a bit. :tongue:
18 May, 2009, JohnnyStarr wrote in the 32nd comment:
Votes: 0
Ok, so not a C++ question per say, but i've always wondered why this is:

victim = d->original ? d->original : d->character;


so, i understand the true/false statement, but what is
d->original


does that mean, if they are the first char to login since last boot?


also, a seperate question:

act_new( "$n gossips '$t'", ch,argument, d->character, TO_VICT,POS_SLEEPING );

so whats the dif between act_new() and act()?
18 May, 2009, David Haley wrote in the 33rd comment:
Votes: 0
One way to find out what the 'original' field of descriptors does is to look for it in the code to see when it gets set. If I remember correctly, it is set when immortals switch into a character; the 'original' field points back to their, well, original character.

I don't know the difference off-hand between act and act_new, but it'd be easy enough to figure it out by reading the respective functions. :wink:
18 May, 2009, JohnnyStarr wrote in the 34th comment:
Votes: 0
Well, as far as act() and act_new()

I dont know much about macros, but this is what it has in merc.h
#define act(format,ch,arg1,arg2,type)\	act_new((format),(ch),(arg1),(arg2),(type),POS_RESTING)


I think the only difference is act_new has a position argument?
18 May, 2009, David Haley wrote in the 35th comment:
Votes: 0
That means that act(a,b,c,d,e) is replaced literally with act_new((a), (b), ©, (d), (e), POS_RESTING), in other words, any call to act is replaced with the same call to act_new, with the position set to POS_RESTING.

A more elegant solution in C++ is to set the position argument to have a default value, so that you only have one function.

In general,
#define A B
means that any occurrence of A is replaced with B.
18 May, 2009, JohnnyStarr wrote in the 36th comment:
Votes: 0
Question:

I am wanting to change the CHAR_DATA structure into a C++ Class.
I'm assuming this wont to be too hard because a structure to an extent
is not that different than a class when it comes to accessing members with a pointer and all that.

So the only code i would have to change would be where i want to enfore OOP, just like David mentioned
with interfaces and such.

Is there anything i'm missing? is this the right step to take?
18 May, 2009, David Haley wrote in the 37th comment:
Votes: 0
You can make a structure a "class" by merely changing "struct" to "class". But this is pointless, except as a stepping stone to actually using class functionality. Recall that a structure is exactly like a class except that all of a structure's members are public, whereas a class can have visibility control.

To answer your last question, it's the right step to take if you plan on making a distinction between public and private variables. But it's a waste of time if you're not going to go anywhere further with it.
19 May, 2009, Caius wrote in the 38th comment:
Votes: 0
David Haley said:
You can make a structure a "class" by merely changing "struct" to "class". But this is pointless, except as a stepping stone to actually using class functionality. Recall that a structure is exactly like a class except that all of a structure's members are public, whereas a class can have visibility control.

To answer your last question, it's the right step to take if you plan on making a distinction between public and private variables. But it's a waste of time if you're not going to go anywhere further with it.

That's not quite correct. Try compiling this small example:
struct TestClass
{
int publicData;

private:
int privateData;
};

int main()
{
TestClass myTest;
myTest.publicData = 5;
myTest.privateData = 5;
}


You'll find that it won't compile because you can't assign to the privateData variable. So the only difference between class and struct is that in a class the members are private by default, while in a struct they're public by default. A struct can also have privacy control.

This is also explained in Bjarne Stroustrup's "The C++ Programming Language" (3rd edition) section 10.2.8.

Edited a typo.
19 May, 2009, David Haley wrote in the 39th comment:
Votes: 0
I keep forgetting that you can set visibility for structs. The earlier compilers I worked with didn't allow it; structs could have methods etc. but putting in visibility control would generate an error.

Anyhow, the point stands that it's not really helpful to "encapsulate" your data if all you do is leave everything public, or worse yet (as it generates a lot more work for you) make everything private but then add transparent getters/setters for everything.
19 May, 2009, JohnnyStarr wrote in the 40th comment:
Votes: 0
Is it possible to get ROM to compile in Dev-C++ for windows and linux?

I see that they have a clean rom for Visual Studio C++ but i tried to get it to work in
linux and it wouldn't. I've really come to love using Dev-C++ allot. And i guess of course i could host my mud
on my windows box. But, because my server is Linux i would like the flexibility of both. :biggrin:

Which brings up something I've wondered, are there any real downsides to hosting my mud on a windows box?
I'm going to end up doing it from home anyway. I was told that Linux has better networking support.
20.0/72