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

Wow, "delete this;"... I can't begin to tell you how unsafe this is.

>>is such a method recommended?
Here is my scale in C++:
- Desirable (includes things like RAII, exception-safety, binary compatibility, generic implementations, concept checking, const-correctness, etc.)
- Recommended (includes things like programming-by-contract, independence, abstraction, encapsulation, non-copyable, smart pointers, etc.)
- Acceptable (includes things like the visitor pattern, dynamic casts, etc.)
- Lesser evil (includes things like singleton patterns, fly-weight idiom, union-types, raw-pointers, etc.)
- Last resort (includes very few things that are horrible, like const-casts and C-style casts, for example)
- Forbidden, horrible, disgusting, evil code (includes almost nothing, but it includes "delete this;")

What if your object is allocated statically (not with new)?
What if your object is allocated as part of an array?
What if there exists another pointer to your object?
...
These are all perfectly normal uses of a class in C++. And they would all lead to a disaster if you decide to do a "delete this;" statement. The const_cast and setting this to null is completely useless. You have contrived an example in which this works, but that's just a very special case. In most cases, the this pointer won't relate to anything meaningful in the caller's code (in a method, the this pointer should always be treated as a read-only local variable, there is no guarantee that treating it any differently will be valid).

If you …

VernonDozier commented: "Forbidden, horrible, disgusting, evil code" +13
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Ok, let me clarify what I think you mean. You would like to have a Log class that does something like this:

class Log {
  private:
    std::ofstream outFile;
    //..
  public:
    Log(const std::string& filename) : outFile(filename) { /*..*/ }; 
    
    void recordEntry(const std::string& S1) {
      //..
      outFile << S1;
    };

    void recordEntry(const std::string& S1, const std::string& S2) {
     //..idem
    };
    
    //... so one for any number of strings. 
};

Well, you might want to learn a few things about templates in C++, before going to deep into this Log class.

C++ does not really support variadic functions (i.e. functions with variable number of arguments) (actually, it does, but it's not type-safe and very ugly, and I don't really know how to use that obscure feature). So, basically, you would have to write a function overload for each different number of parameters (just restrict it to 10 or something like that).

I want to point out two things. First, if you use templates, you will not be restricted to only strings. You can make overloads that take any sequence of parameters of any type:

class Log {
 //.. as before ..
   //say for 3 arguments:
   template <typename A1, typename A2, typename A3>
   void recordEntry(A1 a1, A2 a2, A3 a3) {
     outFile << a1 << a2 << a3; //this will allow you to record anything that can be outputted to a ostream.
   };
};

Second, I want to point out that the upcoming C++ standard (now called C++0x) will include …

daviddoria commented: Very thorough answer! +5
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Line 13 and line 17 look awfully similar... wink wink...

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

@FBody: That won't change the stride of the pointer. The problem is that he has a contiguous array of RGBA pixels (with stride of 4 bytes) and he needs to output a pointer to an Rgb (with stride of 3 bytes). That just cannot be done, polymorphism won't achieve anything to this end. Imagine this situation:

struct Rgb { char r,g,b; };
struct Rgba : Rgb { char a; };

int main() {
  //if you have an array of Rgba:
  Rgba my_image[256*256];

  //you can cast the pointer to a pointer to Rgb:
  Rgb* pix_ptr = my_image;
  //then accessing the first element is valid:
  if(pix_ptr[0].r == my_image[0].r)
    std::cout << "red equals red!" << std::endl;
  //but accessing any element beyond that will be aliased:
  if(pix_ptr[1].r != my_image[1].r)
    std::cout << "red is not equal to red!" << std::endl;
};

This is because, when incrementing the Rgb pointer, the compiler assumes that it is pointing to an Rgb object, and it increments by the sizeof the type (i.e. pix_ptr + 1; is the same as ((char*)pix_ptr) + 1*sizeof(Rgb); ).

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

Why not try it and see for yourself:

#include <iostream>

struct Foo {
  Foo(bool shouldThrow) { 
    if(shouldThrow) {
      std::cout << "Foo Constructor called, throwing exception..." << std::endl;
      throw 42;
    } else {
      std::cout << "Foo Constructor called, no throwing anything :)" << std::endl;
    };
  };
  ~Foo() {
    std::cout << "Foo Destructor called!" << std::endl;
  };

  void someMethod() {
    throw 69;
  };

};

struct Bar {
  Foo f;
  Bar() : f(false) {
    std::cout << "Bar Constructor called, throwing exception..." << std::endl;
    throw 17;
  };
  ~Bar() {
    std::cout << "Bar Destructor called!" << std::endl;
  };
};


int main() {
  std::cout << "\nTrying to create object Foo(true)..." << std::endl;
  try {
    Foo f(true);
  } catch (int e) {
    std::cout << "Caught exception number " << e << std::endl;
  };

  std::cout << "\nTrying to create object Foo(false) and calling someMethod..." << std::endl;
  try {
    Foo f(false);
    f.someMethod();
  } catch (int e) {
    std::cout << "Caught exception number " << e << std::endl;
  };

  std::cout << "\nTrying to create object Foo(true) dynamically..." << std::endl;
  try {
    Foo* fp = new Foo(true);
    delete fp;
  } catch (int e) {
    std::cout << "Caught exception number " << e << std::endl;
  };

  std::cout << "\nTrying to create object Foo(false) dynamically and calling someMethod..." << std::endl;
  try {
    Foo* fp = new Foo(false);
    fp->someMethod();
    delete fp;
  } catch (int e) {
    std::cout << "Caught exception number " << e << std::endl;
  };

  std::cout << "\nTrying to create object Bar..." << std::endl;
  try {
    Bar b;
  } catch (int …
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Ok, I thought that your function getRgb would only affect the user-side code. If you have a complete system that is based on the fact that all images have 3 bpp and are all rgb-formatted, then I would say you have to fit everything you have into that assumption. This is what OpenCV does, all their images are 3 bpp bgr images (but I think that 2.1 version is a bit more flexible, at least I remember seeing some basic use of generic programming).

I think that if you are loading an image that has 4 bpp (whether it is rgba or high color-depth), you should convert it to the format that your software platform requires. You will certainly lose information in the process, but that information is beyond what your platform can handle.

I was a bit shocked to see the two example functions you have posted. Are some functions of that software platform actually programmed like that? That's worse than I thought. It's incredible what damage the idea of "strongly typed" can make when it's wrongly interpreted. Someone has decided, very naively, that all pixels are RGB, made a type for that kind of pixel, and then made the entire platform dependent on that type, and bloated with magic numbers and hidden assumptions. You need a jack-hammer to break through such a rigid software platform, and a lot of man-power.

If you do decide to create another type "Rgba" and overload all the functions to …

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

>>is there anyway I can change this Rgb type to now have the desired stride length?

No. All types in C/C++ have a fixed size, that cannot be changed at run-time. No way.

If you could change the interface, it would be better to output an iterator object which then stores a stride which could vary at run-time (but, of course, it would make the increment/decrement operations much slower).

Another option is to have another function like "getRgba" that returns a 4-byte stride pointer instead. If the user attempts to call getRgb with an image that has 4 bpp, then you throw an exception or return a NULL pointer. Of course, this isn't very nice on the user-side, but that's life.

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

You need at least this to compile any C++ code into a program:

int main() { }; //the { } is very important.

You don't need any code in between the { } to compile, but the application just won't execute anything. If you have either no function called main, or you have the above without the { }, the compiler will not be able to compile it into an executable program.

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

Isn't code injection malevolent? I hope you are not one of those despicable hackers.

>>I understand this class is VERY POORLY DESIGNED.
It's also very incomplete. You are not initializing most of your data members.

>>My question is how can i fix this??
The main problem that I see is that you are allocating resources and performing operations while throwing a bunch of meaningless exceptions. First, you should come up with a set of exception classes that make sense, throwing one generic ERROR exception is just useless, you're not really giving any information to the user of your class as to why there was a failure. Why report an error if you give no information about it?

Second, you need a destructor! Maybe you omitted to post it, but that would be quite a huge omission. When you allocate resources and perform read-write operations in a "preserve the original" fashion, and you are throwing exceptions around, you have to make sure that if an exception is thrown, the state is not left invalid after stack unwinding. That's why RAII is so useful in C++. With RAII, you do the initialization in the constructor (basically, the operations that can fail), and so, if the operations fail, you throw an exception and then the destructor will be called to undo what the constructor did, and at the end, you can make sure that the state of the system is made valid again by the destructor. For example, …

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

Well, first of all, there are 69 characters between 'a' and 'z' in that sentence, not 83 (that's counting the spaces too, which are not counted by your loop).

I would try using isalpha() instead. It's in the #include <cctype> header.

OH, and you should get rid of line 25. Why on earth would you do "charCount=mychar;", it doesn't make any sense. Can't believe I missed that the first time around.

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

The main reason for using const char* is because it is compatible and linkable with C. Many APIs and other libraries have C interfaces (you use the API via a collection of C-like functions). With these functions, you have no choice but to use types that exist in C, which includes primitive types like int, float, char, double, short, etc. and any pointer type (including C++ class pointers, since they are just normal pointers). In other words, you can't use pass-by-value of any class type (including std::string), and you can't use any pass-by-reference of any type.

The reason why C interfaces are used is mainly because C is so simple that it does not need to mangle function names to account for parameter types (which C++ has to do to achieve function overloading), and because types in C have a trivial byte alignment because it doesn't have to deal with virtual tables and multiple inheritance like C++ does. So, C interfaces are preferred for portability and binary compatibility, and along with that comes the burden of having to convert strings to const char* and vice versa (or sometimes write code that uses const char*, just to avoid converting back-and-forth all the time).

In internal code (code that doesn't use an API directly, or code that isn't at the interface of an API), if programmed in C++, I see absolutely no reason to use const char* instead of std::string. The only people using char* in these situations are those …

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

The bound that you use on the loop is not correct. "length" is the total number of characters in your memory buffer, it is not necessarily the number of characters that was read with fgets from the file. C-style strings are terminated by a null character. So, you should add the following to your loop condition:

for ( int i = 0; ((i < length) && (mychar[i] != '\0')); i++) {

This will stop the iteration when the null-character '\0' is found.

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

**PLEASE USE CODE TAGS**

If you sort the list, using "data.sort()". It will put all the characters in order of their binary representation which you can get from the ASCII table. You will notice that all numbers are between character #48 and #57. Any character before or after is a "letter" (or punctuation or something else). So all you need to do is print all the characters in order as letters until you find the '0' character, than print the numbers until you hit any character greater than '9' and then you can just print the rest as letters.

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

Whatever it is that is causing this behaviour is not standard. When I tried your program, line 6 would output garbage regardless of line 12 and 14 being commented or not, as expected. It might simply be that your compiler puts "cow" from line 12 temporarily on the stack frame of main, than frees that piece of the stack frame, and when you call farm1, the cow variable in farm1 just ends up occupying the same place on the stack and thus has a value of 10. In other words, its just incidental. The expected behaviour is for cow in farm1 to have a garbage value when outputted, it's just that in this case that garbage value ends up being 10 because of what was executed just before the function call. Basically, the 10 is a garbage value.

Try this for example:

#include <iostream>
using namespace std;

int cows = 10; //global variable

void farm1()
{
    int cows;
    cout<<"in farm1, cows="<<cows<<endl;
    cows++;
}

int main()
{
    cout<<"in main, cows="<<cows<<endl;
    farm1();
    farm1();
    farm1();
    farm1();
    farm1();
    cout<<"back in main, cows="<<cows<<endl;
}

See how the garbage value is continuously reused because the local "cow" always takes the same place on the stack frame.

jonsca commented: Seems plausible. +7
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

You have no breaking condition in your getline function. The while loop that uses is.get(), when applied to the standard input stream, will never end. Normally, this loop would end when you hit the end-of-file, but cin never reaches that point, it has no end. When there is nothing remaining on the input stream, the get function will just wait forever. Why not implement a true replacement to the getline function:

std::istream& getline(std::istream& is, Str& s, char delim = '\n'){
	s.clear();
	char c;
	if(is){
		while((is.get(c)) && (c != delim))
			s.push_back(c);
	}
	return is;
}
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

The problem is that string is not just an array of characters. First, the array of characters that it does hold is just big enough for the number of characters the string currently has. In this case, you initialize it to " " so it will contain only one character, so that won't be enough to store the result of getline. Second, taking the sizeof(string) will not give you the number of characters that the string holds, it will give you the size of the string class, which is fixed and is not related in any way to the number of characters. To get the number of characters, you would need to use headerInfo.size(). Finally, the string class in not necessarily a null-terminated array of characters, which is what getline will output. You are basically screwing with the string object in a way that will create, at best, undefined behaviour, possibly, memory corruption, at worst, a crash.

Fortunately, there is a very simple solution to this. The <string> library provides a special getline function to read a string from a stream object. It is a global function in the std namespace where you just pass the stream as the first parameter, and the rest is the same:

std::string headerInfo = " ";

  //Verify stream is still in good condition
  if(streamReader->good())
  {
    streamReader->ignore(fileSize, ':');

    std::getline(streamReader, headerInfo, '\n');
  }
  else
  {
    //Error
  }

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

>>OK Mike, is exception handling normally inserted in code, or is it only put in there when you are having problems with your code?

Exceptions in C++ are a mechanism to report certain "abnormal" events that can occur that generally break the normal execution of the program. But, if used, they are part of the normal code, it's not a thing you put if you have problems or something, that's debugging. They are a way of handling exceptional cases that are part of the program's possible behaviour (not a bug or problem with the code). For example, not being able to open a file because it doesn't exist, not being able to establish a network connection because the server or connection is down, not being able to proceed with some numerical calculation because of some divide-by-zero situation, etc. etc. These are things that CAN happen but deviate from normal execution, but they have to be dealt with.

Typically, exceptions are comparable to error-codes (which is more of a C-style way of handling exceptional cases). Say you want to open a file and read a fixed amount of data from it. The normal execution would involve opening the file and reading X amount of bytes from it. What if the file doesn't exist? What if it contains less data than you expected to find? These situation break the normal execution of the operation. There are two common ways to deal with this: error-codes and exceptions. With error codes, what …

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

What code do you have so far?
What did you try?
What is your hold function supposed to do?
What is it about this hold function that you don't know how to do or can't seem to make to work?
...

>>can anyone help me?
We can answer questions or help you solve a problem, but first, you have to describe the problem, ask a relevant question, and show that you have put effort into solving the problem yourself. Answering the questions above is probably a good way to do that.

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

Here is an example of how to tell the fstream to throw an exception if something wrong happened, and how to catch the exception. I guess that is what is required to do. The basic mechanism of exceptions in C++ is with the "throw" "try" and "catch" keywords. Their meaning is pretty clear from their names.

You use "throw" to initiate/create the exception (throw an exception). Now, you can throw anything you like, but it is most common to throw something derived from the std::exception class, and typically it is thrown by value and caught by reference. However, you can also throw primitive types and pointers to objects, but that is less usual.

You use the "try" statement (followed by { } ), to tell the compiler to be watching for exceptions to be thrown. If an exception is thrown, all the actions that were performed from the start of the { after the try keyword to the point where the exception was thrown will be sort-of "undone" (the stack is unwinded).

Following the try-clause (after the closing } ), you follow with a "catch" statement (or multiple ones). There, between parenthesis after "catch", you tell the compiler what kind(s) of exception you want to catch. When the exception is thrown, the stack unwinded up to the try-clause, the exception that was thrown is checked against the catch-statements for correspondance. If you have a catch statement for the kind of exception that was thrown, the …

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

The _start function is something that the compiler generates. It's actually the first function that starts the program (called the entry-point). Nominally, all this function does is call the main() function. If you do not have a main() function defined anywhere (empty source file or whatever), that is the error you will get. You need a main() function, otherwise you won't be able to compile into an executable program.

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

@Rashakil Fol
I think we have a very different point of view on this matter. Probably because of different experiences on different types of software. We might have to agree to disagree. But here is my point of view on some of your comments:

As for A.3, that's correct (except the last sentence), and irrelevant, since it's a hypothetical risk that doesn't really happen.

It might be hypothetical to you, it's not to me. I often split my code into multiple shared libraries in which case there is a lot of "weird" ordering of initialization of different objects, including merging singletons as well. The problem of not being able to have access to valid global variables at ANY time is a very real problem, there is nothing hypothetical about it.

No, you don't. That code will fail in an obvious way under testing. Checking pointers for null values all the time if they're never supposed to be null is a cargo-cult form of robustness. If you don't want it to be null, don't let people assign to it. You could add some bureaucracy around the variable but it won't give you any substantial benefit.

Edit: Worrying that someone might assign a null pointer to the global really is just hysterical. They could just as easily assign an empty std::map, if the thing were not a pointer. If you're worried about somebody misusing a variable, make a wrapper type to only permit acceptable operations.

I agree that testing for nullity …

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

Ok... This might get a bit out of the scope of this thread, but let's do it anyways:
A. Here are some obvious problems with your code:
1) It uses a global variable (ok.. that's not worse than the OP's code).
2) It's a global pointer (which could, obviously point to nowhere).
3) The global pointer is initialized at the start of the main function and thus, puts all the code that executes prior to that into jeopardy. And similarly at clean-up. Global objects should ALWAYS use an initialize-on-first-use idiom.

B. And some coding practices problems:
1) You require all client code to initialize the global pointer with this "unusual" method (unusual in the sense that it is more than a typical new/delete or smart pointer).
2) You require all client code that uses the global pointer to check for nullity in order to remain robust.

C. And finally to the point of the original post:
1) The issue here is to free the memory that is allocated by the std::map object, not freeing the object itself. The object itself is of static storage, so it is not relevant to the problem, it's only its internal dynamic storage that matters (and there are plenty of ways to force that internal storage to get freed without having to devise a scheme that makes the global statically-stored object a global dynamically-stored object pointer that can be freed altogether).

To me, all of …

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

This is a classic problem, you have a dangling new-line character on the input stream. You need to call ignore() right after you input the character to clear that dangling new-line. So, at line 31:

cin >> ans;
cin.ignore();
Khoanyneosr commented: Thanks so much! I'm new to coding and I really appreciate your help. +0
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

call:

ready.open(apply,ios_base::trunc|ios_base::out);
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

If you have more than 1900 of debt at 14%, and you only pay 20 per month, you will never be able to repay your debt, ad infinitum. That's why you get an infinite loop. You should add a check at the start of the loop to see if the yearly payment is at least bigger than the interest accrued before going into an infinite loop (or add a check to see if the balance is actually decreasing from year to year).

Also, the loop at line 17 is redundant to the one at line 19. I think that just removing the one that starts at line 19 would work.

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

I'm pretty sure that swapping with a temporary will solved that problem.

PS: You should use a better memory leak tracker, it sounds like yours sucks. Use Valgrind or something similar.

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

>>Constant pointers mean that once you point to an address, you won't be able to point to anything else?

Yes.

>>So changing the value of an address that a pointer is pointing to is the only way to change the value of the pointer?

The value of a pointer IS the address it is pointing to:
"the value of an address that a pointer is pointing to" = the pointer's value
"the value of the pointer" = the pointer's value
These two phrases are synonymous. Do not confuse the "value of the pointer" with the "value to pointer points to", the latter is the value you get by de-referencing the pointer.

>>All these "Pointer to a constant", "Constant points to constant" are confusing me. Wouldn't "pointer to a constant" be the same as constant pointers? const int* ptr or int* const ptr : these are two alternative syntax for declaring a "constant pointer". This means that the address stored in the pointer (i.e. the pointer's value) cannot be changed after initialization. This does not mean that the value pointed to by the pointer cannot be changed, it can:

int value 111;
int * const ptr = &value;
(*ptr) = 231; //this is ok, dereferencing the pointer and writing a new value at that location.

int const * ptr : This is a non-constant pointer to a constant value. This means that you can change the pointer's value, but you cannot change …

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

>>frowns on stackoverflow.com where everybody is posting relevant pieces of code to actually help each other and not vague phrases

On SO, almost any post that looks anything like a homework/exam question is closed down by moderators in a matter of minutes. Here we rarely shut-down people, we help people who are learning and are having problems with something, whether they are doing it for course credits or personal hobby/interest. In either case, posting ready-to-serve solutions does not help the person asking the questions.

The rules of daniweb are mostly oriented towards the people who ask questions, it is understood that the people who answer them will self-moderate (they usually do, I had a few down-reps myself when I started, but then I learn the trade). You may have a point there, it might be good to have a set of rules laid out specifically for posting to answer questions.

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

You mean besides reducing the scope of the std::map object? You can swap it to an empty temporary container:

int main() {
  std::map<int,int> my_large_map;
  //... allocate a large number of elements in map.
  std::map<int,int>().swap(my_large_map); //swap with an empty temporary
  //at this point my_large_map is empty and the temporary was destroyed.
};

Typically though, you would just reduce the scope:

int main() {
  {
  std::map<int,int> my_large_map;
  //... allocate a large number of elements in map.
  }; // this will destroy the map completely. If you need another map later, just create a new one.
};

However, I have to say that std::map is usually implemented as a self-balancing binary search tree. This is akin to a linked-link type of storage (sequential container), so calling clear() probably does deallocate all the memory in most implementations.

@template<>: I don't think you understood the question.... or I didn't.

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

There are several problems with your code:

In Header:
Line 61 and 62: You are missing the semi-colon at the end of the line.

Line 28: You are missing a semi-colon after }

Line 52: There should be a closing bracket }; at the end of the DynStack declaration. And consequently, you should erase the closing bracket at line 148.

Lines 87, 90, and 116: I'm pretty sure that these should all be ListNode<T> and not DynStack.

Line 121: You need to add std:: in front of "cout" because the std namespace is not imported (and it should not be imported).

Line 91: It should be newValue instead of num.

Line 114: The parameter newValue should be passed-by-reference pop(T& newValue) and should probably be renamed. And so, the definition of pop at line 50 should be updated as well.

Line 125: It should be newValue instead of num.

Line 97: It should be "head" instead of "top".

Line 90: The class ListNode does not have a default constructor, so, you should pass the value "newValue" to its constructor, and that makes line 91 obsolete.

In CPP:
Line 14: You need to provide a type for the class template DynStack. It should be DynStack<int> With all the above changes, I got it to compile very easily. You have to develop a better eye for typos and things like that. These mistakes were trivial to see in one glimpse …

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

>>how to use tree and hash tables and linked lists properly using classes.
This sounds more like you need a Computer Science textbook. Using trees, heaps, hash tables, self-balancing trees, linked lists, etc. etc., these are computer science topics and they generally differ only on the details when it comes to implementation in C++ versus another language. I really don't know any general books in that field (I'm mostly going with specific problems -> specific methods -> wiki-page on it or a scientific paper on it -> implementation).

>>I want to be able to do a basic graphic user interface
This is not a C++ thing either. This is specific to the GUI tool that you can or want to use. I recommend Qt. I'm sure there are plenty of books or online tutorials/resources to help you with that.

>>and use pointers well.
The more you learn about C++, the less likely it is that you will use pointers (at least raw pointers). But surely, you have to know how to use them, I would put this under "basic skills" in C++.

>>Exceptional C++-by Herb Sutter
I haven't read it, but anything by Herb Sutter is bound to be awesome.

All the resources that drkybelk has recommended are are surely very good. Boost is a master-piece of a library, the more of it you can understand and use, the better you are as a programmer, I would say.

I would also …

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

The formula used for rand48, minstd_rand and the built-in rand() function is the linear congruence formula:

x(n+1) = (a * x(n) + c) % m;

Where a, c, and m are fixed parameters and x(0) is the seed value. Any of the random number generators you have proposed are more complex than this and is very unlikely to be any faster. I find it very bizarre that computing the above formula would take up so much of your computing time (unless all you program does is generate random numbers). The reason why rand() might be faster is because rand() is built-in, and thus, it could have been implemented as inlined assembly code (although fairly unlikely). This is actually the implementation of rand():

int __cdecl rand (void) {
  return (((holdrand = holdrand * 214013L + 2531011L) >> 16) & 0x7fff);
};
void __cdecl srand(int seed) {
  holdrand = seed;
};

rand() is not perfect, but simplicity and speed are not part of its problems. As for Boost.Random, using the basic linear congruence methods should be just as fast unless your compiler really sucks. I tested the following program on my computer (with Linux and GCC 4.6.0):

#include <cstdlib>
#include <ctime>
#include <boost/random/linear_congruential.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <iostream>

int main() {

  std::srand((unsigned int)time(0));
  boost::rand48 rng((unsigned int)time(0));
  boost::minstd_rand rng2((unsigned int)time(0));

  boost::posix_time::ptime start = boost::posix_time::microsec_clock::local_time();
  for(unsigned int i=0;i<1000000;++i)
    rand();
  boost::posix_time::time_duration dt = boost::posix_time::microsec_clock::local_time() - start;
  std::cout << "rand() generated 1000000 numbers in " << dt.total_microseconds() << std::endl;

  start = boost::posix_time::microsec_clock::local_time();
  for(unsigned int …
Zjarek commented: It saved my day +2
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>How do you pass an unknown object into a function and save it?
It all depends on how "unknown" the object is. There is a big difference between "it could be one of a few different types" and "it could be of absolutely any type that exists or will ever be created". In either case, the solutions you posted are probably the worst, and that is because C++ is a strongly typed language and there is a good reason why that is... breaking type-safety with a cast to void* is always the very last resort (and very rarely needed in pure C++, if ever).

If it is of only a small number of possible types, you can use a union type. Say you could store an int, a double or a char, Then you could do this:

class MyClass {
  private:
    union value_type {
      char c;
      int i;
      float f;
    };
    value_type data; //data will hold any of the union's member types.
  public:
    //just let type-safe overloading work its magic:
    void set(char value) { data.c = value; };
    void set(int value) { data.i = value; };
    void set(float value) { data.f = value; };
    void get(char& result) { result = data.c; };
    void get(int& result) { result = data.i; };
    void get(float& result) { result = data.f; };
};

If you have more complex types, you can still use the same mechanism: use a union to store any of the types you are expecting and use parameter-type …

mrnutty commented: exactly +7
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Try using the fastest and least consuming random number generator: rand48 (here is the list of all options). The one you are using is very memory-hungry and is not the fastest. Sometimes, it might be worth exploring quasi-random number generators instead (it is found to be faster and just as good for many applications, especially numerical integration (quadrature) and optimization methods).

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

>>Did you ever try being a college instructor?
Yes I did and their's a good chance I will do more of it in the future.

>>He has us read a book online, then tells us to do stuff without any direction.
Sounds like you might want to file a complaint, or at least voice some concerns in the feedback channels that I assume your college has (course/teacher reviews or feedback surveys). Remember that as a college student, you are, in some sense, a paying customer, you have to right to complain if the teachers isn't good. I did see a clear mismatch between the amount you were asked to do and the amount you seemed to have learned prior to starting to work on the problem.

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

Your declaration of Node should come before your declaration of LList. The compiler doesn't know what Node<T> is because this class is only declared later. When it says "expected initializer before < token", it just means that it didn't recognize "Node" in front of "<T>".

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

>>I made the adjustments that you suggested
No, you didn't. You almost did the exact opposite:
1) you didn't merge the two redundant loops (and this is what is causing the weird execution you are seeing)
2) you made userGuess and playAgain global variables instead of data members (in terms of order of preference: data members are best, local variables are also very good, static data members are OK, global variables are EVIL!)
3) you kept most of the code in the main function where it doesn't belong.
4) you didn't split the responsibility correctly as I suggested.

I think you have suffered enough working on this problem. Let me just show you what you would have obtained if you followed the guidelines of my previous post:

#include <iostream>  // Used to produce input and output information.
#include <cstdlib>  // This header is used to produce the random number generator function.
#include <ctime>  // Header used to help with the production of random numbers.
#include <string> // Header used to allow string usage.

using namespace std;  // Allows the use of cout and cin without having to type std in front of them everytime.

class Guess
{
  public:
    int guess;
    Guess(int userGuess) : guess(userGuess) { };
    virtual void DisplayGuessResult() = 0;
};

class High : public Guess
{
  public:
    High(int userGuess) : Guess(userGuess) { };
    virtual void DisplayGuessResult()
    {
      cout << "Your guess of " << guess << " is too high, guess …
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Use a loop:

string name;

cout << "Enter You're Name: ";
while(name.empty())
  getline(cin, name);
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Oh, RELATIVE_PATH is actually not really a MACRO, nor is it predefined. There are usually compiler options to make __FILE__ give just the filename or fullpath (I think that MSVC uses "/FC" and "/ZI" for that, there is probably something similar in GCC). The ERROR macro that I posted was taken from my own code and in my code, all the source files are under a single top-level folder, so I use this RELATIVE_PATH function to parse the __FILE__ string to look for that top-level folder name and output everything after that folder from the full-path. Here is the code for it (my top-level folder is called "ReaK"):

/**
 * This function will convert an absolute path that goes through a folder named "ReaK" and
 * return a the path relative to that ReaK trunk folder.
 *
 * \param S Some string containing a full file/folder path.
 * \return string containing the file/folder path relative to the ReaK trunk folder.
 */
inline std::string RK_RELATIVE_PATH(const std::string& S) {
  for(unsigned int i=0;i + 5 < S.size();++i)
    if(S.substr(i,4) == "ReaK")
      return S.substr(i+4);
  return S;
};
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Code.Blocks uses the GCC compiler (with MinGW). GCC supports variadic templates from version 4.4 up to the current version (4.6.0, experimental). To enable them, you have to compile your code with the compiler flag "-std=gnu++0x", this enables the support in GCC for the draft-version of the upcoming C++ standard, called C++0x. You can verify the version of your compiler either through some menu in Code.Blocks or by finding the installation directory of MinGW and executing "gcc --version". If it is greater than or equal to 4.4, which it should if you have the latest Code.Blocks version (which comes with 4.4), then you go to "build options.." and add to the compiler flags: "-std=gnu++0x" (without the quotes). By trying to compile the code I posted, you can verify that it works.

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

Your question is:
>>When would it be practical to use a pointer to get a value instead of using the value's name?

IF you know the variable's name and have access to it, THEN you can use the variable's name instead and there is no reason to use a pointer to it instead. So the answer is NEVER.

IF you don't know the variable's name or don't have access to it, or the variable simply does not have a name (dynamic memory), THEN you have to use a pointer (or a reference) to access/modify its value.

It's not like it's really a choice (and if it is, then (almost) certainly, using the variable directly is better than using a pointer or reference to it).

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

Line 210 causes a crash, you should never delete a pointer that you didn't allocate yourself. Especially in this case. The pointer returned by str().c_str() is not a pointer that you can delete (the string object will take care of that).

This must be the craziest code I have ever seen. You have some real patience, writing all that repetitive stuff out.

I hate to say this, but your MACROs have reserved words for name. All identifiers, including MACROs, can start with (almost) any character except the underscore character, these are reserved by the C++ standard for implementation-specific needs (meaning that you should not be using any names starting with _ character, that's illegal). Furthermore, the names _1, _2, _3 ... are used by Boost.Bind/Lambda libraries and will soon also be reserved keywords in the upcoming C++0x standard, so you definitely cannot use those.

If I were you, I would save myself all this trouble of writing this ERROR function and just use the variadic template feature of the upcoming standard (you can set the compiler to use its draft-version compatibility (gcc: "-std=c++0x" or "-std=gnu++0x") for now until the standard is officially released). Using variadic templates, you can achieve the same result as your code with the following:

#include <iostream>
#include <fstream>

namespace detail {

template <typename T, typename... Args>
void FERROR(std::ostream& out, T value, Args... args) {
  out << value;
  FERROR(out,args...);
};

};

template <typename... Args>
void FERROR(const char* sourcefile, int sourceline, Args... args) { …
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Here is the solution I got from running it with the parameters you prescribed (100 50 50 1000000).

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

FYI, I launched your program on my home computer (remotely from my office), I will send you the results when I come home later this afternoon.

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

As Agni suggested, you can group all those delays/timers into one singleton object. The same mechanism applies when it comes to calling from the same thread as foo was created or calling from any thread. I will just make an example for calling from the timer thread (you would just have to replace the callback by setting of a flag to signal the call on the original thread).

#include <boost/thread/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/bind/bind.hpp>
#include <iostream>
#include <map>

class publisher {
  private:
    typedef std::multimap< boost::posix_time::ptime, boost::function<void()> > CallBackMap;
    typedef CallBackMap::iterator CallBackIter;
    CallBackMap callbacks;
    boost::mutex callbacks_mutex;
    boost::thread publishing_thread;
    void execute() {
      while(true) {
        {
          boost::unique_lock<boost::mutex> lock(callbacks_mutex);
          CallBackIter it_end = callbacks.upper_bound(boost::posix_time::millisec_clock::local_time() + boost::posix_time::milliseconds(20));
          for(CallBackIter it = callbacks.begin(); it != it_end; ++it)
            it->second(); //call the callbacks that are scheduled.
          callbacks.erase(callbacks.begin(), it_end); //erase callbacks that were called.
        }; //release lock.
        boost::this_thread::sleep(boost::posix_time::milliseconds(20)); //sleep 20ms 
      };
    };

    //private constructor. Will start the execution thread.
    publisher() : publishing_thread(boost::bind(&publisher::execute,this)) { }; 
    publisher(const publisher&); 
    publisher& operator=(const publisher&); //non-copyable.
  public:
    void subscribe(boost::function<void()> f, boost::posix_time::time_duration dt) {
      boost::unique_lock<boost::mutex> lock(callbacks_mutex);
      callbacks.insert(std::make_pair(boost::posix_time::microsec_clock::local_time() + dt, f));
    };

    static publisher& getPublisher(); //singleton.
};

publisher& publisher::getPublisher() {
  static publisher p; //will be created on first use.
  return p;
};

class foo {
  public:
    void my_delayed_method() {
      std::cout << "Hello World!" << std::endl;
    };

    foo() {
      publisher::getPublisher().subscribe(boost::bind(&foo::call_method_with_delay,this), boost::posix_time::seconds(60)); //subscribe for a callback in 60 seconds.
    };
};
Agni commented: Very helpful code +4
arjunaw commented: Kudos to you for taking the time to write sample code showing what you mean. Much appreciated. +0
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

I think that just an ordinary sleep function would do, no?

For example, using boost::thread (I'm not so familiar with native pthread stuff):

#include <boost/thread/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/bind/bind.hpp>
#include <iostream>

class foo {
  public:
    void my_delayed_method() {
      std::cout << "Hello World!" << std::endl;
    };
  private:
    boost::thread delay_thread;
    void call_method_with_delay() {
      boost::this_thread::sleep(boost::posix_time::seconds(60));
      my_delayed_method();
    };
  public:
    foo() : delay_thread(boost::bind(&foo::call_method_with_delay,this)) { };
    ~foo() { delay_thread.join(); };
};

If you need the public method to be called from the same thread as the foo object got created on, then you need to use some sort of signal instead of a direct call:

#include <boost/thread/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/bind/bind.hpp>
#include <iostream>

class foo {
  public:
    void my_delayed_method() {
      std::cout << "Hello World!" << std::endl;
    };
  private:
    boost::thread delay_thread;
    bool should_call;
    void call_method_with_delay() {
      boost::this_thread::sleep(boost::posix_time::seconds(60));
      should_call = true;
    };
  public:
    foo() : delay_thread(boost::bind(&foo::call_method_with_delay,this)), should_call(false) { };
    ~foo() { delay_thread.join(); };
    
    void call_if_delay_passed() {
      if(should_call) {
        my_delayed_method();
        should_call = false;
      };
    };
};

//for sake of example, here is a creator thread:
void create_and_loop() {
  foo f;
  while(true) {
    f.call_if_delay_passed();
    boost::this_thread::sleep(boost::posix_time::seconds(1));
  };
};

int main() {
  std::cout << "About to create several threads... press ctrl-C to stop!" << std::endl;
  
  boost::thread* t[10];
  for(int i=0;i<10;++i)
    t[i] = new boost::thread(&create_and_loop);

  std::cin.get();
  return 0;
};

You will observe that there is nothing thread-unsafe in the above.

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

First, a few random things:

Line 81: it should be a double equal sign ( == ) in the if-statement.

Line 109 and 121: One of those two loops has to go, they are redundant (one loops until the right answer, the other loops for MaxNumberOfGuesses number of times). I think you ought to have ONE loop on BOTH conditions (i.e. loop while still not the right answer AND the number of guesses haven't exceeded MaxNumberOfGuesses).

Now, for where the variables should be. You have to think of this as splitting responsibility between parts of the program. Each class is a part that does something (accomplishes a contract) for the application (and the main() function should merely be "launching" the objects into action, so a typical OOP program will have very few lines of code in the main() function).

Here, you have two very distinct contracts:
GuessingGame: Should execute the game and store all the data necessary for that.
Guess: Should keep a record of one guess that was taken.
Plus three sub-contracts:
High: Should qualify a guess as too high.
Low: Should qualify a guess as too low.
Correct: Should qualify a guess as correct.

By the above contracts, you can split the data (and their use) between classes very easily by asking which purpose they serve. Obviously, the playAgain variable should be in GuessingGame because its purpose is to determine whether the game should continue (and GuessingGame …

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

I just tried this on Linux GCC 4.6.0 and it works:

#include <iostream>
#include <string>
#include <algorithm>
#include <functional>
#include <cctype>

//global operator overload.
bool operator>>(std::string &left, std::string &right){
  typedef std::string::reverse_iterator rit;

  //detect if empty or all spaces.
  if( std::find_if( left.begin(), left.end(), isalnum ) == left.end() ) {
    left.clear();
    return false;
  };

  rit it_begin = std::find_if( left.rbegin(), left.rend(), isalnum ); //find last non-space char
  rit it_end   = std::find_if( it_begin,      left.rend(), isspace ); //find last token's start
  rit it_e_end = std::find_if( it_end,        left.rend(), isalnum ); //find second-last token's end
  right.assign(it_end.base(), it_begin.base()); //set rhs to last token
  left.erase(it_e_end.base(),left.rbegin().base()); //erase last token from lhs
  return true;
}

int main()
{
  std::string input, token;
  std::getline(std::cin,input);
  while(input >> token) {
    std::cout << token << std::endl;
  }
  std::cout << "Input size: " << input.size() << std::endl;
  std::cout << "Token size: " << token.size() << std::endl;
  return 0;
}

Watch out with the use of isspace and isalnum because the versions in the std namespace are templated overloaded functions for the different character types and encoding. You cannot use such templated overloads because their address cannot be taken (at least not as simply), and they have default arguments which make them none-unary. That would be solved by either not using <algorithm> stuff (and spelling out the loops) or using lambdas (from boost or C++0x).

PS: I have no idea what "string iterators are incompatible" is supposed to mean (probably that the first and second parameter of find_if are not of the same type of iterator, …

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

You need an implementation for the functions in all those classes:

class Guess
{
public:
	Guess();
	virtual string DisplayGuessResult();
	int guess;
};

class High : public Guess
{
public:
	High();
	virtual string DisplayGuessResult();
};

class Low : public Guess
{
public:
	Low();
	virtual string DisplayGuessResult();
};

class Correct : public Guess
{
public:
	Correct();
	virtual string DisplayGuessResult();
};

Those with the same name as the class' name is the constructor. The compiler is looking for those functions and can't find them, and thus, throws a "unresolved external symbol" (which translates to "I can't find the implementation of those functions!"). To implement them, you can do, either inside the class declaration:

class Guess
{
public:
	int guess;
	Guess() {
          guess = 0;
        };
	virtual string DisplayGuessResult() {
          cout << "The unclassified guess was " << guess << endl;
          return "whatever?";
        };
};

Or outside the declaration, as follows:

class Guess
{
public:
	int guess;
	Guess();
	virtual string DisplayGuessResult();
};

Guess::Guess() {
  guess = 0;
};

string Guess::DisplayGuessResult() {
  cout << "The unclassified guess was " << guess << endl;
  return "whatever?";
};

I just assumed that you did implement those functions, and that you just didn't post that part of the code. You need to implement them!

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

>>Also, there is a lambda function used I would like to remove without adding another function.

That's easy. Your Lambda is only calling the isspace function, just replace it with the isspace function. As so:

sum = std::count_if(left.begin(),left.end(),std::isspace);

>>I'm comparing a std::string::difference_type to a std::string::size_type

That's ok, it only issues a little warning. If you want to avoid the warning, cast the diff_type variable to the size_type type. Or, you can use end() - begin() to get the size as a diff_type instead of a size_type.

>>Any ideas for an algorithm change?

I think the algorithm is OK. You might simplify the code using more <algorithm> and <functional> utilities. Also, you should probably use the "assign" function instead of clear and insert on lines 41 to 46. The whole #define business for the reversion of the string is very awkward and unecessary. Either choose one, or implement the operator to take an inserter (front_ or back_insert_iterator) as second argument instead (with a default overload for a string). Finally, notice that line 49 is not going to delete the trailing space characters in the left string (you could just use left.end() for the end of the range to erase).