mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

I think these functions should be a good starting point:

FindResource

LoadResource

LockResource

SizeOfResource

And to actually save this to a file, the function you have posted earlier is not good at all. Say you use the above to get a pointer (ptr) and a size in bytes (size), then you save with:

std::ofstream file;
file.open("myfile.dll",ios::out | ios::binary);
file.write((char*)ptr, size);
file.close();
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

As Duki suggested, use the Boost Thread library. You will have to install boost. This library in cross-platform and quite easy to use, and includes all the synchronization objects you can dream of. The C++0x standard will include a thread library, and that thread library will be directly taken from the Boost Thread library (Boost is the anti-chamber for the C++ standard libraries). So I would suggest you get acquainted with that library since, once the standard is out, it will be mostly the same (maybe only a subset of the Boost one), only the namespace will change from boost:: to std::.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

For starters, I don't know how to do what you want. But I do know that the code you have there is completely wrong because of the fact that the handle that is outputted by the LoadLibrary function is not by any means a pointer to the memory where the DLL is loaded into. It is some identifier that the operating system uses to handle that DLL. Loading a DLL is more complicated and intricate than a simple dump of the content of the DLL file into RAM.

Even if you could find some sort of pointer to, say, the entry point function of the DLL or its symbol table (can't remember what it is called in windows), I doubt that you could find a contiguous chunk of memory that has the exact DLL file content (their are things like process contexts, virtual addressing, static memory, pointer translation tables, etc.). When a DLL is loaded, it gets sort of split into parts that are code shared by all processes that use that DLL, parts that are process-specific and a bunch of constructs that put those together.

If all you want at the end is to find that DLL file, wherever it might be in your computer. I would suggest you just do a file search (i.e. search through all the source files for the keyword "LoadLibrary") or if you know the name of the dll, just search through system and system32 folders (and don't forget to tune the …

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

szString1 is actually a pointer (or address) to the start of that chunk of memory with all the characters of the string (terminated by NULL or 0 or '\0', it's all the same). So when you pass szString1 as szTarget to the function, then szTarget also points to the start of that chunk of memory with all the characters. So when the function executes it changes the content of that chunk of memory to hold the concatenated string. Finally, when you return from the function call, the memory pointed to by szString1 now contains the concatenated string too (because it's the same memory that is addressed by szTarget).

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

This is because the function cin.get() will take a char* parameter and the size of the array of chars, and the compiler doesn't find the function that has only a char* parameter.

You should change the "make" variable to type std::string (in #include <string>) and use getline() on the cin instead.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>Form my bookish knowledge this is why there is a exception that is coming with the `friend` keyword.Please correct me that I'm wrong, since op declared this thread as a open discussion. So like to heard form some real on the job experience.

You are right, in your "bookish knowledge" (I like that term). I usually prefer the friend relation with regards to accessing private data members (or in some cases, a nested accessor-class). Because giving full access to a data member with a non-const reference is usually bad because it allows any user to really do anything with the data member. But if the data member cannot break the state of the object, then it is a bit better (of course, you still have the problem that the user could keep the reference to the data member after the containing object has been deleted, which is a horrible bug, but still a const reference will have the same problem). Usually in practice, when you need to use this technique (bending the rules of best practices), you usually give proper comments (doxygen: \pre \post \note \throw, etc.) to warn about the dangers of using the method inappropriately. A friend relationship is better because you can control which classes can temper with the data members, and usually that class is also implemented by you and you can make sure it's safe. But of course, ideally, no friends and no getter/setter for data members that can break the state of the …

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

@NicAx: I've been reading your last few posts... I have to say your language is a bit peculiar. I agree and disagree on what you say, or at least what I understand of what you mean:

>> I do not recommended this code through my past C++ experience.

I don't either, const_cast is never a good idea. It is a last resort (like any other cast function for that matter), and in the OP's case it can be avoided for sure (like the solution I posted, which is not very good either, but better than a const_cast).

>>Think what will happen if the temporary will initialized as just after it returns?

That will never happen, all the parameters sent to a function are evaluated before the function call. And there is no temporary in this case anyways.

>>No sorry can't say good to losing the const.

I can't say it's good either. Returning a non-const reference to a data member of a class is like if the class declares the following semantics: "You can grab my data member and do whatever you want with it, whenever you want." This is valid semantics (not a bug per se) but very poorly designed semantics and ideally should be avoided by design (but if the cost of redesign is too much, then it can be acceptable).

>>The C++ access levels are completely statically checked, and there's no magic way that C++ can detect a access violation …

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>I don't want to provide unrestricted access to the class through the use of friend, so the only other way I can think of is using a getter to pass a reference.

So, ask yourself this question: Is it better to grant complete access to the data members of a class, to another class which you implement? Or is it better to grant access to one data member of a class to the entire software?

You made the second choice... was it wise? Only you can answer that.

I'm just saying that because a big part of making the right design choices is to ask yourself the right questions.

As for the little debate between Narue and firstPerson, I would just say that you are doing the logic flaw of "false generalization". You say that a getter / setter functions are symptoms of bad design (which they are), and thus, the design must be bad (like if you say having freckles is a symptom of skin cancer, so if you see a single freckle on your body you should run to your nearest chemotherapy center!). A getter and setter here and there is nothing to worry about, if you start needing them everywhere, then you have a problem. Even a very good design can have a few flaws here and there, it's not worth the pain to redesign for that ultimate, perfect design just to avoid a few flaws.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Well, this is not a normal behavior for sure, so how to explain it?
I mean, I copy-pasted the exact code you posted (changing buffer to a static array, and taking the delete statement out) and it works perfectly.

What compiler are you using? Is it up-to-date with your linux core version?

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Some compilers don't like it when the source file does not end with at least one empty line. See MSDN.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

In linux, the distributions (Ubuntu, Kubuntu, Fedora, Gnome, ..) and their families (Debian, ..) really mostly differ in where you find things in the computer (e.g. the different services and stuff your software links with). So that's why there are different "packages" for different distributions (usually by family). But really, these packages generally are just different install programs that just contain different compiled and/or linked versions of the same source code. I'm no expert though, but as far as I have seen, all open-source programs in Linux have several distro-specific packages to install the software, but only one download for the source code (compilable on any distribution of Linux). So in that case, implementing for any distro (like Ubuntu) is fine, you might have to recompile for different distros if you want to distribute the application, but even that, I'm not sure you even really need a recompilation, maybe simply a different "install" procedure, i.e. package, will do the trick.

But again, don't take my word for it. I only have experience using programs in Linux, compiling some open-source programs (rolling software versions) and programming non-commercially-distributed applications. So the above is just the impression I have on distribution of Linux software.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Well, I just tested a similar code on my Linux machine (gcc 4.4, with only default options), and it's working properly.

Maybe, just maybe, in your compiler / std-libraries, there is an additional char_traits template specialization for a static array of chars. It would be very weird and non-standard, but it could definitely produce the exact error you are describing. The reason for this is that the std::string class uses this char_traits template class to determine the number of chars that are being appended. By virtue of the template specialization for a char pointer, it will essentially call strlen() on the pointer, which will lead to correct behavior. But, if your particular system defines a specialization for the char[N] type (N being a compile-time constant), the char_traits::length() function might output N (which would be 100 in your case) and then the entire buffer would be appended to the std::string (ignoring the null-character along the way).

But I have to repeat, this _could_ explain the problem, but it is _extremely_ unlikely, at least I would be shocked to know that there is a compiler / std-library provider in Linux which results in that behavior.

NicAx64 commented: this may be the case. +2
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

No no, no need for pointers here. the original solution posted is fine (without the const_cast non-sense). Just do this:

int& get_tp() { return tp; };
..

int Activate(int& tp, int weaponDamage, int attack );

That's totally fine, as long as it is acceptable in your design that the outside code can modify tp at will. Otherwise, you would have to make it a member function of Adventurer or whatever.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

I don't know any good books from the beginning, but I'm sure you can't go wrong with Stroustrup, like ganesh suggests.

I say, once you get through a C++ book that starts from the beginning and ends in somewhat advanced Object-Oriented Programming topics. Then you should definitely get project(s) going on your own (or with friends). A computer game is always a fun start and usually pushes forward heavy requirements in proper software design, but there are plenty of other "more serious" options too (not that I mean that computer game programming is not serious!), like web services, scientific computing, artificial intelligence, robotics, databases, etc., you take your pick! The world of programming is virtually free and open to you, you let your imagination drive you!

As you progress through your projects, you probably want to check out the Parashift FAQ Lite which has tons of answers to all those specific questions that will arise (you know, questions like "what happens if I...?" "am I allowed to...?" "is it recommended to...?" etc.). And get used to referring heavily on www.cplusplus.com and other reference website that use strict language and precise explanations (often beginners find those a bit cryptic).

Once you are able to pretty much go through that entire FAQ Lite without getting any surprises about things you didn't know or didn't understand, then you are a pretty advanced programmer already (at least in terms of knowledge in C++). But don't try and …

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

@firstPerson: the point is not if the members make sense or not for the classes, it's about how to best implement the I/O for base and derived classes.

@gerard: Here is what you should be doing, in my opinion (and this is what I actually do in my own code):

//IO interface for all the classes:
class printable {
  public:
    //this pure virtual method will be called to print the derived class' object.
    virtual std::ostream& print(std::ostream& output) const = 0;
};
//with overloaded operators:
std::ostream& operator<<(std::ostream & out, const printable & rhs) {
  return rhs.print(out); //simply call the print method.
};


//then your own class hierarchy:
class animal : public streamable
{
  public:
    animal(const char *name):itsname(name) {}
    virtual ~animal() {}
    
    //override the print function in each class that has any new data members.
    std::ostream& print(std::ostream& output) const {
      return output << "animal's name->" << itsname;
    };
  protected:
    const char *itsname;
};
class mammal:public animal
{
  public:
    mammal(const char *name, unsigned long val):animal(name), itsweight(val) {}
    virtual ~mammal() {}
    
    //override the print function in each class that has any new data members (and call the base class method too).
    std::ostream& print(std::ostream & output) const {
      return animal::print(output) << " - " << "mammal's weight->" << itsweight;
    };
  protected:
    unsigned long itsweight;
};
class dog:public mammal
{
  public:
    dog(const char *name, unsigned long weight, unsigned long age):mammal(name, weight), itsage(age) {}
    virtual ~dog() {}
    
    //override the print function in each class that has any new data members (and call the base class …
Narue commented: Yes. +22
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>But the C functions are not depreciated by either C or C++ standards, and that's the only ones that count.

I beg to differ, the implementers (or authors of the run-time libs) also count when it comes to deprecated functions. If the standard says a function is deprecated, it just means the lib implementers are no longer required to provide that function and might not, and that's why you need to avoid them even if your platform still has them. But MS compiler warnings about deprecated functions go the other way too, it can mean that the function is there because the standard requires that function to be there, but the implementer warns you that it might not be wise to use it.

Microsoft provides the C run-time libraries for its OS and it can happen that some of its functions, although kept to conform with standards, can have some hidden issues. MS calls them "security" issues, like they call everything else a "security issue" or "security update" or "security feature"... when really what they mean is they had screwed up the implementation before and now they "fixed" it, i.e. "more secure" as in "less chance of crashing", but now they are stuck with an old, backward-compatible version they don't recommend you use, without admitting it has a bug (and thus, marking it as deprecated).

I've had that problem in the past.. yes it can cause a real problem, it is not just a theoretical thing. It …

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

First, is the external DLL file working?

Second, maybe you should open the file with ios::binary flag as well. Maybe, I'm completely wrong though, I'm not expert on file systems. I can only suspect it is some sort of file header information

Third, are those file sizes obtained from the "properties" popup thing, or did you make a little program to open both, seek the end, and see if their sizes match. Maybe that's useless, I just don't trust Windows to do even the simplest thing correctly.

Finally, did you try and check what the difference between the files are (in linux you would use the "diff" command, don't know in windows). Most probably the difference has to be localized, i.e. only at the start or the end would make some sense.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

I agree with sfuo, this is a matter of output formatting, not of the actual precision of the stored floating-point value. By default, the output format is somewhat automatic in the sense that if you have a number that is reasonably close to 0, it will be outputted in normal format (not scientific) and with some default number of digits (probably 5 or 6, from what you posted). Just set the precision to a really high number (like 25 or something) and you should see a difference between the float, double, and long double.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Yeah, that's true, some compilers consider pretty much any C functions as deprecated (which includes all the functions that operate on C-style strings, i.e., char*). The code you posted just there is quite alright, in the sense that it's just an exact replica of the original strdup() function. It is a good idea to get rid of any warnings like "deprecated", because, although they are often benign, they sometimes hide a real problem and even just reimplementing the simple function like you did there is a bit safer.

But still, repeating my last point in my original post, in C++, if you want to completely avoid "deprecated" stuff, just use C++ standard libraries (including std::string) and no C libraries at all (besides maybe <cmath>). The only reasons I know to use C libraries is if you don't have a choice (like a weird / old platform) or would just like to first get a grip on the basic C mechanisms that are somewhat fundamental to C++ (which can be quite beneficial).

EDIT: Just saw AD's post: No.. please.. don't disable warnings.. always compile with all warnings and make sure to get rid of them all. I know Microsoft's compiler is particularly nagging, but still, treat warnings as errors because they often hide a subtle one.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Wait! are you trying to convert it to a string or a binary memory dump?

If you want a string, as a char array, like one char '0' or '1' for each bit, then use the to_string() function. Like this, for instance:

bitset<128> bits; //say you have 128 bits.
char binstr[129]; //that requires 128 chars + 1 null-char to store it in.
strcpy(binstr,bits.to_string().c_str());
woody1144 commented: Sorted a problem that I had spent 6 hours on, thanks! a* +0
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

I'm guessing the to_ulong() function is not good enough, i.e., you have too many bits in the bitset. If you can use it, then you can always memmove() the resulting unsigned long into an array: char[sizeof(unsigned long)].

If the bitset is bigger, consider splitting it up.

Otherwise, I don't know, I guess you would have use a loop, which, of course, defeats the purpose of the bitset. I don't think the C++ guys expected people to use bitset for anything larger than unsigned long. I know it is inefficient, buy one loop could be:

bitset<128> bits; //say you have 128 bits.
unsigned char binstr[16] = {0}; //that requires 16 bytes to store it in.
for(int i=0; i<16; ++i) {
  for(int j=0; j<8; ++j) {
    if(bits[j + i*8])
      binstr[i] += 1 << j;
  };
};

sorry, can't help you more than that.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

This loop is wrong:

while (!fin.eof())
{
  while (getline(fin, line))
  {

  }
}

First, the outer condition is good, it means you want to read until the end of the file. The problem it that inside, you are reading all the lines in a loop and always overwriting the string "line" (maybe you thought they would get appended to the "line", but it overwrites it completely every time). So, of course, at the end, you will get only the last line that was read from the file.

This should fix it:

while(!fin.eof()) {
  string next_line = "";  //create a temporary to hold the next line to read.
  getline(fin,next_line); //read the next line.
  line += next_line;      //and append it to "line".
};
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

use another letter.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

goto is evil! You would do good to take it out of your programming vocabulary!

Now, how on earth is this code supposed to jump to rec, sq, or cir? You never test the ch that is input. Since your choices are numbers, you should input a number, not a char, but that's acceptable too. If you input a single char, you need to also call cin.ignore(); after that input because you will have dangling characters on the input stream that will make the subsequent inputs behave bizarrely.

Here, you should use a switch-case statement to determine what to do after the choice input, and forget the goto business.

Finally, you should use more obvious names for your variables. Single letter names are unreadable and have no meaning, not to mention that you might get name clashes with this kind of code (for example, you have a variable called x and a label called x, I don't know how the compiler treats it though because goto is evil and I never used it for that reason).

For the rest, it seems alright to me.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

The logic is alright, but there are many mistakes and improvements to be made:

1. If you want to store 7 digits as a char array, using the %s input, you need to have at least 8 chars in the array, because there is a null-character at the end of the string to tell where it ends. To be robust to the possibility that someone may enter more than 7 digits, you should also make the char array much bigger (like 256 or something).

2. You use the "function" sizeof() to get the length of the string in charPtr. This is wrong, the sizeof operator only gives the size of the type it is given, in this case the type is a pointer, so the result will be 4 bytes (32bit system) or possible 8 bytes (64bit). To get the length of the string pointed to by a char pointer, you need to use strlen() instead.

3. If this is supposed to be C++, you should know that printf and scanf are deprecated, and now std::cout and std::cin are in use. Also, std::string is much better than char* or char[] for holding strings. But for the rest of this, I will assume you are actually doing a C program and not a C++ program.

4. If you input a 7-digit number, why do you need to input it as a string? Why not use an integer number instead, using:

int InputNumber = 0;
scanf("%d",&InputNumber); //%d …
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Please post the code between code tags, and indent it properly.. it's horrible to look at code that has no indentation:

#include <stdio.h>
#include <conio.h>

int main()
{
  char charPtr[7];
  int smallest, largest, middle, intNo;
  int dividend=0; int modolus=0;
  int valid;

  do {
    printf("Enter a seven digit number:\n");
    scanf("%s", charPtr);

    valid=0; // counter for no of digits
    for (int i=0;i<sizeof(charPtr);i++)
    {
      intNo=(int)charPtr[i]-48; // trap if 0-9
      if (intNo>=0 && intNo<10) // trap invalid other than 0 to 9
        valid++; // increment counter
    }
    printf("valid=%d\n",valid);

  } while (valid!=7); // repeat if counter is not equal to 7

  for (int i=0;i<sizeof(charPtr);i++)
  {
    intNo=(int)charPtr[i]-48;

    if (intNo>=0 || intNo<10) // trap invalid other than 0 to 9
    {
      printf("%d = decimal=%d, ",i,intNo);
      if (i==0)
      {
        smallest=intNo;
        largest=smallest;
      }
      else
      {
        if (i==3)
          middle=intNo;
        if (intNo<smallest)
          smallest=intNo;
        if (intNo>largest)
          largest=intNo;
      }

      // compute binary
      printf("binary=");
      do {
        modolus=intNo % 2;
        dividend=intNo/2;
        intNo=dividend;
        printf("%d",modolus);
      } while(dividend!=0);
      printf("\n");
    }
    else
      printf("None Entered\n");
  }

  printf("Smallest=%d\n",smallest);
  printf("Largest=%d\n",largest);
  printf("Middle=%d\n",middle);
  printf("Decimal\t\t");

  float intDec=0; // initialize
  for (int i=sizeof(charPtr);i>0;i++)
  {
  }
}
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

The idea in your second solution is the right one, you want to copy the memory from the string that is passed to a newly allocated string. That's exactly correct and proper. The only problem you have is that you used sizeof() to get the length of the string. This is not the right function. sizeof() is a "function" to give the size in memory of whatever variable or type you give it. In this case, the variable you give to sizeof() is textVal which is of type (char *) which is a pointer to a character, and on your system, a pointer has 4 bytes (32bit), so sizeof(textVal) will always give 4 (on your system). That's why you get 4 characters "menu" correctly copied to the new string, but the rest is gibberish.

The function to get the length of a string (C-style string, which is actually a pointer to the first char, of course) is the function strlen(). So, replacing sizeof() by strlen() will solve almost all the problem.

Another issue is that a C-style string has a null-character at the end to indicate the termination of the string. So the actual size you need to allocate for the new string is not strlen(), but strlen()+1, for the null-char. The same goes for the memcpy operation, also strlen()+1. You can also use strcpy() instead of memcpy().

Now, what happens if myValue already points to something? You need to check that it points nowhere or somewhere …

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

There is _maybe_ a tricky way to do this. Since the == operator is not required to be inside the class definition of pair, you could implement it outside of it. Now the problem will arise with the two conflicting functions: the original (somewhere in the std namespace) and your own. Now, it's all a matter of namespacing. If you define your function in the global namespace, the compiler will look for the == operator and find it in the std namespace before it reaches the global namespace and your overloaded version will never be called. Now, on the opposite, if you put that overloaded operator == in a namespace below the std namespace like this:

namespace std {
  namespace my_dirty_hack {
     template<typename T1, typename T2> 
     bool operator ==(const pair<T1,T2>& p1,const pair<T1,T2>& p1) {
       return (p1.second == p2.second);
     }; 
  };
};

Then, by being VERY VERY CAREFUL with where you call the == operator from, you might just be able to get away with it. This uses the idea that compilers look for the overload operator or function starting from the namespace where it was called and then move up the namespaces. I'm not even sure if this can actually be done, because it is very tricky, and I don't know how to avoid getting the compiler to go crazy over this hack.

Another dirty hack to accomplish this is to do a template specialization of pair. If, in your case, this is only needed for one type …

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

@FirstPerson: Let me clarify:
>>"Simplest and best" are subjective terms
You're right they are subjective, so let me expand on my subjectivity. I say "simplest" because it is most concise and all the necessary information about start, condition and increment of the loop are in one line that is easy to read for the mildly-trained eye. I say "best" because the integer value i is local in scope to the loop only, while the others will keep it alive until the next end-of-scope. But you are right, the compiled code will most probably be the same and as efficient in either cases (except perhaps for the additional variable in the scope containing the loop, which some may argue could be a tiny bit more efficient).

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Memory in a computer is always organized in a pyramidal way. That is, the processor can only operate on a few variables at a time (on the register, very small memory capacity at no clock-cycle away from the processor). A program can only run a small part at a time (on the cache, a few MB, at a few hundreds clock-cycles away from the processor) on a small amount of memory (the stack). The program as a whole can only be loaded into memory that is too far from the processor to execute directly from there, but which is much bigger (a few GB of RAM, a few hundred thousand clock-cycles away from the processor). And all the data and programs are too big to be stored there and need to be in the hard-disk (a couple of millions of clock-cycles away from the processor).

This stratification of memory is essential for performance and most of it is handled automatically by the OS. The OS takes care of taking chunks of code and memory from the RAM, putting it on the cache. Then your compiled program takes care of putting a few variables at a time on the register for the processor to perform one operation.

Our point is, that if you put too much memory on the RAM and try to work with it as a whole, you only get the illusion that you do work with it as a whole when actually most of that memory …

Ancient Dragon commented: Nice :) +33
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Did you make sure that SDL_LoadBitmap() has a valid output. In other words, those the bitmap load properly? Because the tutorial gives a Unix-style file path for the image, maybe it is wrong?

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Wikipedia
I never heard of dynamic scoping, and to no surprise after reading this wiki. There is no dynamic scoping in C++, and frankly, I'm happy there is none because it seems more hurtful than helpful.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

You have been looking at the wrong swap function. He means the swap function in the <algorithm> header. see this page on it.

If you don't understand the template syntax, just assume it works for any type "T", and leave it at that for now. You would use it as, say:

#include <algorithm>

..
    swap(vector[0],vector[2]); //leave vector[1] as before.
..
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Here is a good article on initialization lists.

>>How much code can go in an initializer list?

As much as you can while keeping the code neat. This means, don't go overboard trying to fit everything in the list, make sure it stays understandable and readable. Aside from that, there are do's and don't's. First you need to initialize any member or base class that does not have a default constructor, because anything missing from the list will be constructed with the default constructor and if it is not available (private or absent) the compiler will complain with an error. That includes references (data members that are references to something), they can only be assigned once, on construction, so they need to be set in the initialization list.

Second, you cannot (or should not) refer to the this pointer or use any data member of the class to initialize any of the data members.

Third, you cannot call a virtual method, neither can you do that in the body of the constructor anyways.

From the top of my head that's about it. You can call functions, do math operations, whatever, as long as they are initializing the data members or base classes. You cannot put general expressions like "member1(init_value), some_function_call(), member2(init_value2), .." between the commas.


>>Can I call new SomeClass() to get a pointer to initialize something even if it wasn't in the original argment list?

Yeah sure, why …

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

First read this, then this, and finally this.

I'm not sure I fully understand what you are trying to do (can you show some pseudo-code).

If you are trying to simply re-use the code to do the initialization of the class, then, of course, a separate initialization method (function) would do the trick, or default arguments to the constructor can also achieve this, if applicable. NOTE: do not attempt to make the initialization method virtual, this will crash your application (read the third link I posted).

If you are trying to literally call another constructor, for whatever reason, within another constructor. Forget it. That's not possible and for good reason. It might be possible with some very convoluted and dirty hack, but that's hard because it should never be done for any reason. In other words, if you are clever enough to be able to implement this kind of a dirty hack, you should be clever enough to find a way to avoid needing to.


In general, the usual idiom to use in this kind of case is the "factory function" idiom. This means you make a static method that wraps the "new" call for the class and also includes a post-constructor initialization function. This allows you for example to make the constructor private and enforce the construction through the factory function instead. By convention, people call that static method "Create", as in the following:


       
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Working with such a big array is going to be very slow and troublesome. Even if you make it work on your computer, will it work on another?

I would suggest you think about the algorithm you have which uses this array and see if it is not possible to split the array in smaller arrays and reuse the memory. Try make your algorithm parallel and the memory usage more local. In other words, rearrange the algorithm such that you can allocate a smaller array, work with that subarray to get the sub-output, save the output and load a new subarray and repeat. You could use the harddisk to save and load the subarrays to and from a file (that's what the OS will probably do with swap memory anyways, and it will be very slow, so it might be better if you do this swapping with the harddisk).

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Change the type of display_Desig at a pointer to char, char *. And with the single equal sign for assignment, it should fix the compilation error.

For the rest, there at least two small things to change / add:
1. change the type of all those B_SAL, H_ALLOW... variables to float (or double), since they hold floating-point values.
2. add a line "cin.ignore();" at the end of the loop, just after "cin >> repeat". This is due to the fact that since you read only a single character, the rest of the user input will be left dangling on the input stream and repeating the loop might yield undesirable effects. You can try without that line to see what happens.

All-in-all, it's quite a good beginning!

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Here are a few facts:
1. If you hold a map of objects (not pointers) of the base class, then it's going to be objects of the base class, not a derived class, that's impossible without a very nasty hack (reinterpret cast on the object). DON'T DO THAT!
2. There is no way to implement a copy-constructor in a base class that will achieve the copy of the derived class, without an even worst and absolutely horrible hack (involving a memmove() on the "this" pointer). DON'T DO THAT!
3. You cannot use a reference to a base object either because references cannot be assigned (or re-seated).

There are many alternatives to achieve what you want, or what I guess you want. Here are a two good ones that I could recommend:
1. use a map of pointers to the base class objects, or better, use smart pointers like std::TR1::shared_ptr<> or std::TR1::unique_ptr<>.
2. use the Pimpl idiom to encapsulate the pointer to the base_impl class and then you can hold and copy the base objects with properly designed methods. This is from a previous post of mine on this thread on a very similar subject:

class BaseClass {
  public:
    class Impl {
      public:
        //Here, you would list all those virtual methods you want.
        virtual void someMethod() = 0; 
        //This methods needs to be implemented in each derived class to call its constructor (with new).
        virtual Impl* clone() throw() = 0; 
        //virtual destructor, …
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Maybe the precision is not good enough. Is it running in any sort of time that you know for sure is more than 1ms? If it does definitely take more than 1ms, then, as david said, try to inspect the tick count values directly to see if the GetTickCount() and your conversion to milliseconds is working as expected. If it might be that your algorithm is too fast for the precision of the clock or, more probably, of your conversion method, then simply run the algorithm many times, say 1000 times, and divide the profiling result by 1000.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

The other use of break is to "break" out of a loop. For example, the following three loops have essentially the same behavior (of course the first one is the simplest, best and most efficient):

const int N = 20; //upper-bound

for(int i=0; i<N; ++i) {
  //.. do something
};

int i = 0;
while(i<N) {
  //.. do something
  ++i;
};

int i = 0;
while(true) {
  if(i == N)
    break; //this will terminate the loop and jump to right after the "};" of the loop
  //.. do something
  ++i;
};
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Ok, so the statement you are having an issue with is:

if(!head)

Lets go by it step by step. First, the if-statement, of course, takes a boolean value (true or false) and executes the next statement if that boolean value is true.

Then, the ! operator is the NOT boolean operator (logic operator) it simply takes a "false" and turns it into a "true", and vice versa.

Finally, the head is a pointer, but the NOT operator is for a boolean value. So, C/C++ provides a implicit conversion from pointer to bool. This conversion returns a "true" value for any pointer that is not NULL, and "false" if the pointer is NULL.

So the statement if(!head) will do this:
For a NULL pointer head:
- the head pointer will be converted to the boolean value "false".
- the boolean value "false" will be flipped by the ! or NOT to become "true".
- the if statement will recognize the "true" value and execute the following line.
For a non-NULL pointer head:
- the head pointer will convert to a "true" value.
- the "true" value is switched to a "false" value.
- the if-statement will not execute the following line (and execute the "else" case if one exists).

So, conclusion, this statement does exactly what the author describes.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

In this case, the struct is, IMO, totally appropriate. And NO, there is no functional difference between classes and structs except for the default access rights (private, public) which you shouldn't use anyways because it is better to be explicit about the access rights.

In this case, the data inside the struct is the interface of the type (see Plain-Old-Data types "POD"), there would be no point in hiding it in a class' or struct's private scope and providing some mutator / accessor methods. The only real difference between struct and class is in the minds of most programmers who tend to use struct as a simple "package" of data, with few methods, i.e., the data in the struct is the interface defining its purpose (to hold a bundle of associated data).

Just use the struct you have and implemented the required operators for it to work on a set<>. From the top of my head, you are required to have a valid copy-constructor, assignment operator and a less-than operator. The first two are provided by default by the compiler and in this case your struct is simple enough that the default will do just fine. So all you need is the less-than operator (and you might wanna add a few more useful comparison operators and others while you are at it).

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>I am using the modulo operator with a double when it can only be used with ints.

Although you don't need it here, if you do need in the future, the modulo function for double is fmod().

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Every floating-point representation like float, double, or even long double, will inherently have a round-off error. Usually, for these three types it is rounded-off around the 7, 16, and 20 significant digit (although long double may not be different from double, and the precisions can change per platform).

So, even simple operations like +- will not yield exact results (in the sense of continuous real numbers, because it would take infinite space to hold an infinitely precise number). The round-off errors are subject to the same operations as the numbers, so they propagate and accumulate. This is why, for some algorithms, there is significant analysis done to get an estimate of the propagation and accumulation of round-off errors. Techniques to mitigate that problem include: parallel computations where a possibly larger amount of calculation but smaller independent sequences of calculations can reduce the accumulation of error; and interval arithmetic can also be used to replace a value with a lower-bound and upper-bound on its error, this way, at the end, you can get the uncertainty interval of the computed value (this is a bit extreme because it more than doubles the computational load, but it is used sometimes, where, for example, the result uncertainty could make the difference between an airplane designed to crash and one designed to fly!).

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Just throwing in my grain of salt.... I'm mainly a Linux user so I may be biased.

I find mingw (as I assume it is the same as the Linux gcc) to be much more helpful in general. It is easier to know that your are compiling and the error and warning messages I find more clear (I often have trouble with the wording used by the microsoft compiler, and I hate having to go through menus to change the compilation options). Not to mention that all the evidence I have seen lately makes me believe gcc produces more efficient code and is also more up-to-date and compliant with the latest developments of the C++ standard (BTW, that quote from Bjarne is outdated by two years, a lot can and has changed since then).

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Simply make a MACRO to wrap the function call:

//in MyDebugUtilityFunctions.h

void ReportError(int lineNumber,Wstring ErrorTitle,Wstring ErrorMessage)
{
  ... report the error ... 
};

#define MY_DEBUG_ERROR_REPORT(X,Y) ReportError(__LINE__,X,Y)

//say in the main.cpp, or anywhere else.
int main() {
 ...
  MY_DEBUG_ERROR_REPORT("Fatal Error!","The main function crashed here!");
 ...
};

The MACRO will ensure that the __LINE__ corresponds to the right place, and no just the line of your print function. Also, you may want to consider using the __FILE__ define as well, which is set by the compiler to be the file name of the source file or header in which it is (you would add that to the MACRO and as a parameter to your report error function).

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

@Fbody: you covered two good cases, but none are about the OP's question.

If you have a nested class, then the this pointer, within a call to a member of the nested class, refers to an instance of the nested class (not its wrapper class). However, the nested class has the advantage that it has potential access to all the methods and members of its wrapper. If you want access to both the nested class and the wrapper class, here's the usual trick: (and I put some const, as a wink to your previous posts ;) )

#include <iostream>

class Wrapper {
  private:
    int value;
 
    void bar() const {
      std::cout << "The answer is " << value << std::endl;
    };
 
  public:
    class Nested {
      private:
        Wrapper& Parent;
      public:
        Nested(Wrapper& aParent) : Parent(aParent) { };
        void foo() const {
          Parent.bar();
        };
    };
    Wrapper(int aValue) : value(aValue) { };
};

int main() {
  Wrapper A(42);
  Wrapper::Nested B(A);

  std::cout << "What is the answer to the ultimate question of life, the universe, and everything?" << std::endl;
  B.foo();
};
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

This page might help, but I'm sure it's the first you found in researching this issue.

I know why the error happens. "this" and "this" are different. Let me explain. The this pointer you pass to the function is of type TitleScreen* but can be implicitly casted up to a DisplayObjectContainer* (as a base class of TitleScreen). The problem is once transformed into DisplayObjectContainer* it might not point exactly to the same address in memory (this is related to the support for multiple inheritance). This means that if you were to pass the "this" that was casted to DisplayObjectContainer* to a pointer-to-member-function of the class TitleScreen, once inside that method, the this pointer might be offset and thus invalid. This is why C++ will not allow you to pass a pointer-to-member-function that is not directly from DisplayObjectContainer class or one of its base.

So simply put, if the function you are calling says (DisplayObjectContainer::*), then you have to call it with &DisplayObjectContainer::..something..

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>what is the int in operator++(int)
It's just used to differentiate the two functions. It means nothing at all.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

I see one big problem. You should not do anything complicated in the DLL entry point function. This is because there are certain intrinsic properties that make the DLL_entry somewhat different from a normal function call. These special things have to do with the OS being able to load the resources for the DLL while doing some initialization. Simply put, the context of the DLL process is not fully formed at the DLL_entry point and this varies from OS to OS (also from version to version).

For example, it is not recommended (or almost forbidden for good practice) to load an external DLL at the entry point. Launching threads of execution is another highly discouraged practice (the OS could deadlock them automatically because of the incomplete context in which they are started)

All you can do really is initialize some static data, create some sync objects and that's about it.

So in your example, you should at least move all this cascade of calls to another function that you require the caller to call immediately after the DLL is loaded and before any other function call to that DLL (or you can use an internal flag to check the initialized status to be able to initialize before executing any other function, but there will be an overhead on each function call that you may or may not want to live with).


When you ask if this is good practice for program structure. That's very …