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

You wrote "List" instead of "list", C++ is a case-sensitive language.

Because the compiler does not recognize the "List" as a type (and thus starting a declaration of a parameter-list), it thinks that line 12 is a declaration (and initialization) of a "variable or field" called "start" and because it sees it as a "void" type, it gives a compilation error.

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

>>Sarcasm? I hope. Cause this is c++

No. It's not! C++/CLI is not C++. It's a completely different language and it's more akin to C# than anything else.

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

Your operator overload defines an operator for Number + int, not for int + Number. Even though mathematically, addition is commutative, the compiler does not assume it is because you could define an addition operator that shouldn't be commutative.

Anyways, to solve the problem, you should define two operators, one for each case. Now, the int + Number version cannot be a member function, i.e., it cannot be a member of the "int" type, so it has to be a free-function. And usually, the other one should too. As so:

class Number
{
 public:
     int value;
};

inline int operator +(Number n, int v) { 
  return n.value + v; 
}

inline int operator +(int v, Number n) { 
  return n.value + v; 
}
Cainer commented: thanks +0
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>i did this but not sure if its what the exercise asks

That looks OK to me, except that your vector should be a vector of integers if you plan to store integers. That is:

vector<int> elements;  //not vector<bool> elements;

Another idiomatic way to fill that vector is using the assign() function, as so:

IntegerSet::IntegerSet(int a[],int size)
{
    elements.assign(a, a + size);  //picks the elements from a[0] to a[size-1].
}

Or, better yet, if you have learned about initialization lists in constructors, then you can do:

IntegerSet::IntegerSet(int a[],int size) :
                       elements(a, a + size) //initializes "elements" with values from a[0] to a[size-1].
{ /* nothing to do here */ }
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

It is quite easy to check the validity with C++'s formatted input mechanism, which will fail if the input is not of the required format.

Personally, I don't like to fiddle around with the std::cin too much, so I would recommend the intermediate use of std::stringstream.

Something like this would do:

#include <iostream>
#include <sstream>
#include <string>
using namespace std;

int main() {

  int value = 0;
  while(true) {
    cout << "Please enter an integer number: ";
    string tmp;
    getline(cin, tmp);
    if( stringstream(tmp) >> value )
      break;
  };
  return 0;
};
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

It's a classic problem with class templates and friend functions.

Basically, the problem is that the friend-function declaration declares a function, not a function template. So, when you instantiate the class List<int> , the compiler will instantiate all the member function declarations (not their definitions). The instantiation of the friend-function declaration registers with the compiler that there is a function with this prototype:

ostream& operator << (ostream& os, const List<int>& s);

Which is NOT a function template, just a regular function.

So, when you provide the definition of this function template:

template <class T>
ostream& operator << (ostream& os, const List<T>& s) {
  //...
};

The compiler just sees this as an _overload_ of the friend-function. And, because regular function always have priority over function templates when doing argument-dependent look-up (ADL) of function overloads, the compiler always selects to call the friend-function (because it is not a function template). Finally, since you don't have a definition for that function, the linker complains with a "undefined reference" error because it cannot find the definition of that function anywhere.


So, how to fix it? Here are three options in order of preference:

Option 1: Avoid making a friend-function. In most cases, there will be very little difference between using only public member functions to implement your free-function, and using a friendship relation to access the private/protected data members. Especially considering that all the member functions of a class template can be inlined by the …

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

Your deep-copying is essentially correct. But you are really complicating things by not using the std::string class instead of char-arrays. Always prefer using RAII classes when they are available.

I also recommend you read my tutorial on building a RAII class.

As for your code:

Line 10 is useless.

Line 15 is incorrect. It should be delete[] ptr; because the ptr points to an array.

Line 41 is useless. This line just creates a temporary local variable that is called "ex" and that is never used. Your compiler should complain with a warning about an unused variable, if not, I remind you that you should always compile with the highest possible level of warnings (-Wall on GCC).

You have a lot of constructors, and most of them don't initialize all the data members. Even if you wish to default-construct a data member, you should make that obvious by putting it in the initialization list anyways.


With all those changes in mind, you should get this:

class Bullet {
  private:
    int x, y;
    int dx, dy;
    int startingX, startingY;
    std::string name;

    Extra ex;

  public:
    Bullet();
    //~Bullet(); //destructor not needed because all members are RAII.
    Bullet(const std::string& aName);
    Bullet(int startX, int startY, int moveX, int moveY); //

    //copy-constructor and assignment are not needed because all data members are RAII.
	
    int getX();
    int getY();
    int getDx();
    int getDy();
    int getStartingX();
    int getStartingY();

    void move();
    void show(SDL_Surface*, SDL_Surface*, SDL_Rect);

};

Bullet::Bullet() : …
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Disregard what Scholl-R-LEA just said. This loop is correct:

while (in_stream >> number)

In fact, the above is the idiomatic way of reading from a file and it is correct. The operator >> does indeed return a reference to a istream, such that it can be chained. However, the istream type is implicitly convertible to a (void*) type which is only NULL (which then converts to "false") if the istream object is no longer in good condition for input (e.g. hasn't reached the end-of-file marker for example).

The reason you get garbage in the "array" is because you call the print function before you call the load function, so "array" is still uninitialized when you print it.

The reason you get 0 in the vector is because, again, you call the print function before you call the load function, so the vector is filled with zeros because that's what you construct it with (default fill-value is zero).

Just put line 42 before line 40-41 and you should get what you expect.

However, there are some additional issues.

First, your function prototypes should not be in the body of the main() function. I'm not sure why your compiler accepts it or if it should (but I don't think it should). You should declare your functions outside the main() function, that is, before it. So, you should put lines 8 to 11 before line 6.

Second, your code is not safe. What if there are …

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

>>how many instances of the static test t are getting created.

One.

>>What will happen?

Add this to your code:

if( ( &a.t == &a.t.t ) && ( &a.t.t == &a.t.t.t.t.t.t ) )
    cout << "All test t instances are the same!" << endl;

This is just due to two things: a static data member is "globally unique" to the class; and a static member can be access either through "my_class::my_static_member" or "my_object.my_static_member". So, the a.t just accesses the static member of the class, and since a.t is also of the class "test", accessing a.t.t also accesses the same static member, and so on for a.t.t.t, ad infinitum.

The reason why it is allowed to have a static data member of the same class as the containing class is because, since it is static, it is not required to build an object of the class. By opposition, the following code will not work:

class test {
  test t;
};

This is not possible because in order to construct an object of class "test", it requires an object of class "test", this is not possible (i.e. a sort of infinite recursive paradox). So, the compiler would complain saying that "t" is an invalid data member because it is of an incomplete type. When the data member is static, then it is not required to construct an object of that class, so there is no paradox, it works and the compiler allows it because …

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

Why don't you program your UI in C++ and with a cross-platform GUI tool, like Qt. Qt will work everywhere. You most probably want to do your Windows coding in GCC to make sure it will compile with no problems on other OSes. Also, focus on using cross-platform libraries for anything else you might need, like threading and networking. The Boost libraries are very good for that. I also recommend you use a cross-platform build system, Qt more naturally uses qmake, but you can also use cmake.

You will need to have access to both a Mac and a Linux PC to check if your program works there, but you just need that to compile your program once it is almost complete. As long as you never use OS-specific libraries, there shouldn't be any problems. Macs are also fairly close the *nix systems.

If you have a PC, you can easily install a Linux distribution on a USB key and boot from the USB device and you will be able to test your code on Linux that way if you don't want to permanently install a Linux distro on your computer's hard-drive.

To really compile code for Mac, from a PC, you need to setup a cross-compilation. That's not an easy task in general, and I don't recommend doing it (cross-compilation is more typical when you compile for a system on which you wouldn't be able to compile anything …

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

>>so I need _native_ , OS independent functions.

If you expect that the C++0x thread library will be native code, you are greatly mistaken. Threading models are a feature provided by the OS (e.g. doing multi-threading on Linux or Windows is very different, whatever library you use). If you are implementing a basic operating system, then making a threading library is one of your tasks, you won't find a native library for threading that doesn't require having an operating system of some kind running. The C++0x threading library, like the Boost.Thread library, are just OS-independent in the sense that the way you use the library is exactly the same from one OS to another, but the underlying implementation relies on the OS features and kernel calls.

You do understand that compilers you can use to compile an operating system to run on a computer natively have libraries that are very different from typical standard library implementations, and are more limited, because most of the things that you take for granted are accomplished by the OS kernel (like dynamic memory allocation, threading, file IO, any other kind of IO, etc.). Standard C/C++ library implementations are provided for an OS and rely on that OS to provide the features it provides, so these are not _native_ functions.

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

Why don't you read the instructions yourself?

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

You cannot directly link to a DLL like that, as the error says.

To link to a DLL, you can do it either statically or dynamically.

Statically, you need an "import library" (or "interface library"). This is a .lib file that acts as an intermediate between the linker of the compiler suite and the DLL file. Developments suites like MinGW provide tools to generate a .lib file from a DLL. With MinGW, you can use the dlltool program to do that. I don't know about MSVC though, I'm sure there is an equivalent, or that the MinGW dlltool program might produce a .lib file that is compatible with MSVC too.

Anyhow, you have to create the header file manually, and don't forget the extern "C" specification on your function prototypes. You include the header file that you have created for the DLL, and then you link to the .lib file and make sure the DLL is available at run-time for the application (either in the same folder or installed in a standard system folder (usually "C:\Windows\system" or "C:\Windows\system32").


Dynamically, you can use LoadLibrary / GetProcAddress / FreeLibrary (or dlopen / dlsym /dlclose under *nix systems) functions to load the DLL (at run-time), get the function pointers to the functions you have in the DLL, and unload (or free) the library once you are done using the functions of the library (i.e. before exiting the program).

In both …

Ketsuekiame commented: Perfect explanation +8
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Like sfuo said, the || and && operators are for boolean values, so, you need to put two conditions (or expressions that evaluate to a bool value) on the two sides of those operators. In this case while(random != 0 && random != 1) , which reads as "while 'random' is not 0 and 'random' is not 1".

It is also good to know that the || and && operators are also short-cut operators. It means that, for example, if the first condition already evaluates to true in a or-statement, the second condition will not be evaluated at all because it is not needed to get the result of the overall expression. Similary, in a and-statement, if the first condition evaluates to false, then the second condition is not evaluated at all. This can be very useful, for example, to check if a pointer is NULL before dereferencing it:

while (ptr != NULL && *ptr != some_value )

The second condition *ptr != some_value will not be evaluated if the first one is false (meaning that the pointer is NULL, in which case you couldn't dereference it).

sfuo commented: Good to know about the pointers +8
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Beginner's guide to C++0x:
Avoiding Memory Problems by Design of Ownership

If you ever read any resources on C++ programming or object-oriented programming, you must have heard some rethorics like "inheritance is for the is a relation, composition is for the has a relation". Is that all? Is that the end of the story? What is the underlying motivation for this dichotomy? What if my case fits neither category?

The point of this tutorial is to answer those questions and show how to translate the answers into real C++0x code. This tutorial is really about thinking about the relationships between the objects that constitute a software.

We can already answer the first question: Is that all? No. Programming tasks are rarely simple, and applications of object-oriented programming are no exception, meaning that relationships between objects can be complex, and so, no, the "is a" and "has a" dichotomy is not all there is to object-oriented design.

If you have read the title of this tutorial, you have also read the answer to the second question: What is the underlying motivation for this dichotomy? Ownership. The "is a" and "has a" dichotomy is really there to separate what specializes what and what owns what. Off the bat, of course, even these broad relations are not enough, it's missing the "unrelated" relation. In some sense, there are three poles, i.e. no-relation, specialization and ownership, that bound the continuum of possible relations between objects in a software. Needless …

alwaysLearning0 commented: nice +5
kvprajapati commented: Many thanks! awesome :) +15
Ancient Dragon commented: Excellent :) +14
Labdabeta commented: Bookmarked reference page now! +6
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Blender is a pretty good editor and it supports many formats.

The world of 3D file-formats is seriously lacking a wide-spread standard format. It used to be 3ds, when only 3D Studio Max existed as a decent editor. Now, there are many 3D editors, many formats, and most game-studios have in-house formats too.

For the kind of thing you are looking for, you might want to use X3D. It also has some open-source libs to manipulate them, but since it is an XML format, you can also just use a generic xml library.

Ketsuekiame commented: Totally forgot about X3D as we use in-house formats ^^ +8
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Post your code between the code tags [_CODE_] [_/_CODE_] (with no underscores).

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

>>If I am just "using" it then does it mean, my function names are still in global namespace

Yes. The using statement simply makes it so that you don't have to qualify the namespace anymore when you _use_ things from that namespace. It doesn't mean that your code gets added to that namespace. Here's a quick example:

#include <iostream>

namespace foo {

  void print1() { 
    std::cout << "printing in foo!" << std::endl;
  };

};

namespace bar {
  
  using namespace foo;

  void print2() {
    std::cout << "printing from bar!" << std::endl;
  };

  void print3() {
    print1();     //call foo::print1() without needing foo::
  };
  
};

int main() {
  foo::print1();  //OK
  bar::print2();  //OK
  bar::print3();  //OK
  foo::print2();  //ERROR: print2 is not a member of namespace 'foo'
  print1();       //ERROR: print1 is not a member of the global scope.
  bar::print1();  //ERROR: print1 in not a member of namespace 'bar'
};

You get the idea, adding things to namespace 'bar' even though it uses namespace 'foo' will not add those things to the 'foo' namespace. And the logic goes the other direction too (e.g. "print1" from 'foo' does not get added to namespace 'bar'). So the using namespace statement is simply to shorten the syntax, but you can get into trouble, as so:

//.. as before

namespace bar {
  
  using namespace foo;

  void print1() {
    std::cout << "printing from bar!" << std::endl;
  };

  void print2() {
    print1();     //ERROR: print1() is ambiguous, do you mean bar::print1 or foo::print1.
  };
  
};

Sometimes, problems like that don't get …

mrnutty commented: I admire your ability to exhaust an answers! +13
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

You cannot use an array that big. Your problem definition specified a limit of 1Mb, I guess it means you need to stick to that. You say that 6 digit numbers or less works fine in your range array. But more that 6 digit, i.e. 1 million, would cause the range array to be at least 8 Mb in size (each long long is at least 8 bytes), that is already way above your specified limit, and it also happens to be above your program's limit too, and that explains the error.

You need to find another strategy than holding all the values. For example, you could hold every 10 value and interpolate in-between them. It also depends on what function you have, you might be able to manipulate the math somehow to store only a subset of all the range and be able to efficient compute any other value from that subset.

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

Now size of final will be: 4032. as Final will have common A through B and C. Here is the break down of the memory allocation:
4000 for int array.
4 for int c in C + 4 byte padding.
4 for int b in B + 4 byte padding.
16 byte for vtable pointer.

Just a correction on the breakdown of memory allocation. None of the classes have virtual functions, so they will not have vtable pointers. Here is the correct breakdown (in order):
4000 bytes for int array in A.
8 bytes for the pointer to the virtual base-class (A) object of B.
4 bytes + 4 bytes padding for the int b in B.
8 bytes for the pointer to the virtual base-class (A) object of C.
4 bytes + 4 bytes padding for the int c in C.
___
4032 bytes in total.

In order to implement virtual inheritance, all the classes that are virtually derived from a base-class will need a pointer to the "this" pointer of the virtual base-class because it could move with respect to the derived class's "this" pointer depending on the overall inheritance hierarchy.

I also recommend Marshall Cline's explanations of it. Here

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

>> Now I need to register callback function so that when Model is done it will update view using that callback.

You have stumbled upon the reason why I don't like MVC very much. The "idea" of MVC is that the Model should be only a slave to the other components (I say "idea" because it's an old theoretical idea from a time where GUI was more theoretical than practical). Generally, people realize this by having the View run in a loop, always querying the state of the Model and updating anything that changes (or updating everything). Similarly, the Controller runs in a loop catching events of user input. While the Model just sits there, being a slave to the other two. For the Controller, it is totally appropriate. But for the View, it is just stupid and wasteful. So, yeah, you need callbacks initiated by the Model in order signify that some things have changed and need to be updated in the View. But how?

The idea of MVC is to separate the three things, but to what level? Conceptually or computationally. If you just want to conceptually separate the View from the Model, then you need to create an abstraction that wraps the notifications that the View wishes to respond to. Personally, I like to use the Visitor Pattern for this (and it is pretty much the only place I use it), in a manner that implements Inversion of Control. This way, on an abstract level, …

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

I'm no expert on audio/video streaming. On most of my projects, either other people dealt with that, or we had an off-the-shelf solution requiring no additional low-level implementation.

In any case, contact the hardware's manufacturer and ask them about the methods suggested / provided for outputting audio/video stream. As for libraries that are typically used for that, I don't really know, the only libraries I know (besides manufacturer-provided libraries) are gstreamer and opencv (an ex-colleague of mine got one stereo-camera system, three free cameras and a pivoting laser range finder all working with OpenCV, and it took him a few weeks to get it all up and running, so it seems pretty easy to do).

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

>>Union with a name seems a lot like a structure or a class,

That's because a union is a heck of lot like a struct or class except that all members share the same address in memory and the union is as large as the largest (aligned) data member it contains. Other than that, unions are similar to structs and classes in many ways, they can even be templated, have member functions, etc. But they have several restrictions, like they cannot have virtual members, cannot contain non-POD data members, cannot be part of an inheritance scheme, etc. According to the standard (C++98), unions are considered to be a kind of "class". And the new standard will even expand the capabilities of a union-types.

>>but a union without a name seems pointless to me.

It is certainly not pointless. Say you want a class that has some data members to occupy the same memory and others to have separate places in memory, then you can use a nameless union for that.

>>So whats the point of it?

The point is to simplify the syntax such that you don't have to name the union data member each time you want to address it.

>>The first example just looks like a declaration of data type inside a declaration of another data type

That's exactly what it is.

>>and that supposed to be impossible,

Who told you that? Declaring a type within a type is …

sergent commented: that explains a lot! Thanks! +5
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Well, the new standard came out yesterday. It's not even published yet. Don't expect C++0x / C++11 books just yet. And be even more patient for compliant compilers.

Right now, the best resources for C++11 are:

The C++0x wikipedia page.

Bjarne Stroustrup's C++0x FAQ page.

The last published draft of the standard. n3242. Which is pretty much the same as the FDIS that was just approved.

And some tutorials that exist out there, including mine.

Ancient Dragon commented: good stuff to know :) +17
jonsca commented: Agreed, and nice tutorial +14
Chilton commented: Thanks a lot for the help. +3
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Instead of bothering yourself with doing copies of backup files with the tilde mark. I would suggest you just use a subversion control system. I recommend Git. At any time, you can retrieve the entire history of the modifications to any of your source files ("diff" style). That's very easy to use, and git is not centralized, so it does not require a server running it or anything, that's what I do for all my work files, including files that aren't source files, I can keep a triple backup of all my files (and their entire modification history), on three separate hard-drives.

As for build system, I recommend cmake, it is much nicer than those all-too-limited makefiles.

To solve your problem with the makefile, I can't really help you. You should probably not implement this mechanism in a makefile, use a shell script instead, which you can call from your makefile "backup" target.

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

This is a really weird error, and I'm sure there is something you are not telling us. My guess would be that the audioBuffer gets relocated.

The fact that you reallocate or change the std::vector member (I assume is held by value in audioBuffer, as it should) should not cause your pointer to it to be wrong. That's simply impossible in C++. The only way that is possible is if the audioBuffer object gets relocated, which would relocate the std::vector member along with it.

You will need to post more details about the implementation of ResourceHolder and AudioBuffer, because the error cannot be diagnosed from this simple description. One thing for sure, it is not a problem about the std::vector object somehow relocating itself, objects cannot do that in C++, because of value-semantics, objects are only relocated (moved or copied) when their owner (parent object) gets moved.

Generally, it is bad practice to "export" a pointer to a data member from an object. That's dangerous code because you can never be sure that the data member still exist or is still at the same place in memory. Find an alternative. Also, rely on you compiler to optimize things, for example, there is no advantage to do this:

AudioBuffer* audioBuffer   = resourceHolder->getAudioBufferPointer();
std::vector<float>* vector = audioBuffer->getVectorPointer();

// blah blah, read the vector
x = vector->at(0);
// use the vector again and again.

Compared to doing this:

// blah blah, read the vector
x = resourceHolder.getAudioBufferPointer().getVectorPointer().at(0);
// …
harryhaaren commented: Good advice, clearly worded +1
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Well, pretty much everywhere in the code, you use a single < where you need two (outputting with streams). That will fix your problem. And you also need to #include <cstring> to get the strlen function.

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

Why does the database function needs to be passed anything? From the looks of the function, all it does it use the "f" variable as a local variable, and it doesn't use its passed-value for anything. Just make it a local variable and make the database function a function without parameters.

The error is pretty obviously because "f" was never declared in the menu() function, just like the compiler says. You could declare a variable "f" in menu() and pass it to database(), but I see no point in that, because database() doesn't use that value.

Finally, if you want to practice your C++ programming, maybe you should try not to use C functions (like fopen, printf, etc.).

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

>> I have not given a size to the vector.Could it be because of that?

Well, if your vectors are empty, how could you expect to be able to access elements of them? I think people reading your example assumed it was not real code, just an example of the syntax that was erroneous.

Is your error occurring when you run the program or when you compile it?

You have to populate a vector with elements before you can access any. That's pretty obvious.

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

As for the libraries, I would recommend to use well-established cross-platform libraries. For your purposes, SDL and/or OpenGL are candidates of choice. Start with SDL and add OpenGL when you want to take your graphics one step further.

Programming a graphics computer game is a lot different from simple console programs. There are several things to handle.

1) Multi-threading: Almost all graphics computer game have to run on more than one thread. Typically, you need a thread to loop and render the graphics, and a thread to capture and handle the user input. For handling threads, you should use either Boost.Thread or the C++ standard thread library (if you have a recent-enough compiler, with C++0x support), but these two libraries are basically the same anyways. The important part in this topic is to learn to work with a program that does several things concurrently, which is not an easy thing in general.

2) File-handling: Any computer game will have to rely on several files and file-types. Whether it is simply some BMP files, or audio files, or some more complex 3D models and environments, and other custom files, you will have to deal with this. You have to learn to select appropriate formats, appropriate external libraries to handle them, and learn to interface between external libraries (learn to use the "PImpl" idiom to your advantage, make a clear separation (or firewall) between your code and external libraries). File-handling also requires not so trivial …

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

In the simplest possible way, it means:

Dear mister compiler,
In this place (or scope), I would like to be using this namespace that they call std . This would really help me because I won't have to qualify everything with std:: in the remainder of this scope.
Thank you.

And then, the compiler will do it. But, beware of the dangers of name-clashes if you abuse this feature.

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

>>I don't get why that's called static polymorphism?

Static: A mechanism which occurs at compilation or linking time.

Polymorphism: A programming language feature that allows values of different data types to be handled using a uniform interface. The concept of parametric polymorphism applies to both data types and functions. A function that can evaluate to or be applied to values of different types is known as a polymorphic function.

The example I showed fits perfectly into that definition, and this is why it is called static polymorphism.

>>All that's doing is generating multiple function for each type. There is nothing polymorphic about it.

Yeah, so what. There are, obviously, many other things that can be done in generic programming as well. But anyways, what about dynamic polymorphism? All it does is look-up a function pointer in a table, "there is nothing polymorphic about it". Polymorphism is an abstract concept, the implementation details involved in realizing it don't matter. It's the design perspectives that matter.

>> Polymorphism is more like a 1->many relationships, while that's like 1->1 relationship, that is each type has its own function.

You are right and wrong. To the compiler, it is just one function for each type, but this is after the fact, because it is done at compile-time, so, once compiled, the code is not "polymorphic" in the (1 -> many) kind-of way. But, once compiled, the polymorphism has already been realized. If you take the case of …

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

I can only give you an example in C++, because, to my knowledge, you cannot do compile-time polymorphism in Java. (and anyways, such a question belongs in the Java forum)

This is dynamic polymorphism in C++:

#include <iostream>

struct Animal {
  virtual void doCry() = 0;
};

struct Dog : Animal {
  void doCry() {
    std::cout << "Woof Woof!" << std::endl;
  };
};

struct Cat : Animal {
  void doCry() {
    std::cout << "Miaou.." << std::endl;
  };
};

void makeAnimalCry(Animal& a) {
  a.doCry(); // this call will be dispatched (at run-time) to the correct implementation.
};

int main() {
  Dog d;
  makeAnimalCry(d);
  Cat c;
  makeAnimalCry(c);
  return 0;
};

This is static polymorphism in C++:

#include <iostream>

struct Dog {
  void doCry() {
    std::cout << "Woof Woof!" << std::endl;
  };
};

struct Cat {
  void doCry() {
    std::cout << "Miaou.." << std::endl;
  };
};

// this function will be generated, at compile-time, for the given type of animal.
template <typename Animal>
void makeAnimalCry(Animal& a) {
  a.doCry(); //since this is generated at compile-time, no dispatch is needed, this is simple a normal function call (and possibly inlined as well, which is not possible in general in the dynamic case).
};

int main() {
  Dog d;
  makeAnimalCry(d);
  Cat c;
  makeAnimalCry(c);
  return 0;
};

Java is a language with JIT (Just-In-Time) compilation, so it is hard to distinguish compile-time mechanisms from run-time mechanisms, because it runs and compiles at the same time. And the JIT compiler can probably resolve some polymorphic …

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

Or maybe something along the lines of:

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main() {
  ifstream infile("input.txt");
  ofstream outfile("output.txt");
  int value;
  while(infile >> value) {
    char mod_val = (--value) % 52;
    outfile << string(value / 52 + 1, 
                      (mod_val < 26 ? mod_val + 'a' : (mod_val - 26) + 'A')) 
            << endl;
  };
  return 0;
};
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>How can I be a programmer who can understand the codes and writes neat and clean code.

You learn by experience, like anything else, practice makes perfect. If you are comfortable with the syntax of a language and the general logic of programming, then the next step is usually to start getting outside textbook examples, outside the comfortable world of standard libraries, outside your comfort zone. I mean, start writing projects that are complex enough (for you) that they require building a non-trivial software architecture (requires some thought into the design), that they require doing things you have never done and don't know how to do, and that they require using external libraries for doing things you can't or don't want to do yourself (like loading some file-formats (images, databases, etc.), or interfacing with some system, making a GUI, or using peripherals). Pick something you like, nobody can tell you what that is.

You learn to _understand_ code (other than your own) by being exposed to other people's code or to the interface or design of existing libraries. Be curious, and take it one step at a time (i.e. don't start by digging into Boost.Proto or some other crazy complicated library like that, start by looking at libraries that are small and simple enough that you could possibly be able to do it yourself, if you wanted to).

You learn to write _neat_ code as you make mistakes (that you won't want to repeat) and as you …

jonsca commented: Great info, Mike +14
Ketsuekiame commented: Perfect answer +8
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

You don't need those #defines for linux and windows. There are a number of "standard" preprocessor defines which can tell you for what OS and compiler the code is being compiled for/with, in addition to a lot of other things (like C++0x support, multi-threading stuff, etc.). Here is a list for discriminating between the OS.

For example, you could just do:

int realmain() {
  //real work for the program goes here
}

#ifdef _WIN32
int WINAPI WinMain(
  HINSTANCE hInstance, 
  HINSTANCE hPrevInstance, 
  LPWSTR lpCmdLine, 
  int nShowCmd 
) {
#else
int main() {
#endif
  return realmain();
}
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

I believe that the difference is that Windows actually makes a difference between programs that run as a console application (MSDOS) and programs that run in the Windows system (Win32). If you try to run a program that uses WinMain() from a console window, you will probably get the message "This program cannot run in console." (at least, on older versions of windows that still had a native MSDOS environment available, newer versions only emulate the MSDOS environment via the "command prompt"). In Linux, and other *nix environments, all programs run in the terminal (whether you see it or not), and the GUI environment is nothing more than an external library invoked by the program.

But I might be wrong, it has been a while since I implemented any GUI app for windows, but I don't remember ever doing it without a WinMain function as entry-point. Also note that many cross-platform GUI libraries will hide away the entry-point function and provide you with a secondary function that acts as the entry-point for your purposes (which is usually invoked after the basic setup of the GUI application have been done).

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

Well, you are going to need to do simple input/output with the user and with a file.

For user input/output on the console, you will need <iostream>, with cout for output and cin for input. See this tutorial.

Then, you will need to use std::string to manipulate strings, to be able to write some text to be typed, and capture the text that was typed. Then you will need to be able to compare the strings (output and input) to figure out the success-rate, that's probably going to involve looping through the characters of the strings and comparing them.

Finally, you will need to use functions from the <ctime> header to time the user-input.

Do each of these things one at a time, and you will be in great shape.

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

You have fell pray to the "static initialization order fiasco". Read the linked article, and you will understand the problem and read about the solution.

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

I think that the first thing to do is to get a container for all the unique words that describe numbers (not compounded). If in English, that's not very hard or very many. The unique numbers run from 0 to 19, then 20-30-40..90 and 100-1000-1000000.., everything else is a compounded of these unique words. I would suggest you use a std::map<int, std::string> to store the associations of the numbers with the corresponding word, but only for those unique numbers. As so:

#include <map>

int main() {
  std::map<int, std::string> num_words;
  num_words[0] = "zero";
  num_words[1] = "one";
  num_words[2] = "two";
  ...
  num_words[19] = "nineteen";
  num_words[20] = "twenty";
  num_words[30] = "thirty";
  ...
  num_words[90] = "ninety";
  num_words[100] = "hundred";
  num_words[1000] = "thousand";
  num_words[1000000] = "million";
  num_words[1000000000] = "billion";
  ....

};

At this point, you can devise grammar rules to compound those number-words to construct any given number (up to some maximum). The first rule could be:

cout<<"ENTER NUMBER";
  cin>>number;

  if( number < 21 ) 
    cout << num_words[number]; //all numbers from 0 to 20 are not compounded.
  else if( number < 100 ) {
    cout << num_words[ (number / 10) * 10 ]; //extract the ten-multiple.
    if( number % 10 != 0 )
      cout << "-" << num_words[ number % 10 ]; //extract the last digit (1 to 9).
  } else ....
  //... so on for more complicated rules.
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

The is a complete set of functions from WinAPI to "browse" the folders for the files. Personally, I think they are crap (annoying and kind-a hard to use). But, that is what the Open/Save file dialogs use in MFC or win32.

I would recommend you use Boost.FileSystem, it is much nicer (actually in C++), and is cross-platform.

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

Because the date in a "tm" structure is counted from year 1900. Which means that 2011 is stored as 111.

Generally, if you want to print a string from a time_t structure, use the function "ctime". Or, to convert from "tm" structure, use "asctime" or "strftime" for special formatting.

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

To give a more useful answer, that is, knowing what typically could happen when you delete a pointer twice might help you recognize the situation if you see those symptoms.

So, although it is undefined behaviour, as arkoenig mentioned, there are a number of things that would typically happen if you delete a pointer a second time, but it is, of course dependent on the implementation and the circumstances:
1) Nothing at all. It goes unnoticed and doesn't have a visible effect.
2) Heap corruption. The heap is asked to free a chunk of memory that is already freed or already allocated to something else, and because the heap is essentially a data-structure that does book-keeping of the free and allocated memory chunks, but at the same time, the heap typically cannot bare to do too much verification of the integrity of the requested allocation/deallocation, the result of deleting a pointer a second time can easily result in the heap being corrupted (i.e. it screws up the heap's book-keeping).
3) Crash. If the heap can verify that the pointer is already freed, or if the pointer happens to now be pointing outside the virtual address space of the program, the program will crash on either an access violation (seg. fault) or just a plain "abnormal termination".

If you see these symptoms or alternation between them (like changing something small in the code makes you jump from one symptom to the other), then you can suspect …

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

>> it looks to me more like a function

Or like the construction of an object, which it is.

If I have a class named "my_class", I can create an object of that class with "my_class()", which means the object is default-constructed and doesn't have a name (a temporary). So, the "exception()" just creates a temporary object of class "exception" that is default-constructed. The "throw" keyword takes whatever you give it (e.g. object) and propagates it (or carries it) back to the first try-block it encounters, where it will attempt to match it to one of the catch-statements.

You need to provide the throw statement with something to throw, it is most usual to give it a temporary object since there is usually no point in creating the exception object before throwing it, but in theory you could also do:

try
{
   cout << "  Function throwException throws an exception\n";
   exception e; //create exception object.
   throw e;     // and throw it.
} // end try
catch ( exception & ) // handle exception
{
   cout << "  Exception handled in function throwException"
        << "\n  Function throwException rethrows exception";
   throw; // rethrow exception for further processing
} // end catch

But why take two lines of code to do what one lines does equally well:

throw exception(); //this is pretty much the same as above (but less wasteful).
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Your expression "shapes - shapes[1]" takes the difference between the two pointers, not the two objects. You need to dereference the pointers before you apply the difference operator. As so:

*(shapes[i]) - *(shapes[1])

Also, I would suggest you make your operator - a friend function instead of a member function, as so:

friend float operator-(const Shape& lhs, const Shape& rhs)

This is preferred for all operators which are not required to be member functions.

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

Beginner's Guide to C++0x:
The Big Five - Implementing a Resource-holding RAII Class


This tutorial will show how to implement a resource-holding class showing practical use of C++0x features. A resource-holding class is any class which holds, with its data members, a resource which could include:

  • dynamically allocated memory
  • an internet connection socket
  • a file stream
  • any other handle to an operating system resource (e.g. window or thread handle), or
  • an opaque pointer from an external library.

The main characteristic of a resource-holding class is the requirement to allocate (or create) the resource (capturing a handle or pointer to it) and then releasing the resource.

This type of class is fundamental to practical programming because a C++ programmer will very often face situations in which low-level data structures are needed or when it is required to interface C++ code to external libraries (or APIs) which often provide C-compatible interfaces based on handles or opaque pointers ("opaque pointer" is a general term for a pointer which is provided via some API functions and should only be acted on (or dereferenced) from within the API functions, not by the user of the API, so, to the user, it is not really known to what it points to, and is thus "opaque"). The preferred strategy to handle these situations is to create a C++ class which wraps all those low-level functions and API calls, and provide automatic, encapsulated handling of those low-level details, hiding them …

mrnutty commented: Haven't read it al, but deserves recognition for the effort. +13
m4ster_r0shi commented: Very informative! +7
Tellalca commented: keep it coming +4
JasonHippy commented: Excellent tutorial on C++0x. Nice one! +9
happygeek commented: thanks for the tutorial +12
alwaysLearning0 commented: Cool!! nice start +4
sergent commented: Awesome!!! +4
WolfPack commented: Great work. Keep it up. +12
kvprajapati commented: + +15
Sky Diploma commented: ++ +9
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

I think that your intent with the dm_energy_vec class was to just make an alias for the vector<float> type, this can be done with a typedef, as follows:

typedef vector<float> dm_energy_vec;

Then, all your code should work.

If you actually want to make the dm_energy_vec class more complicated (not just an alias for the vector of floats), then use firstPerson's solution.

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

Calling the destructor does not erase the object. It is just like calling any other member function on the object. What makes the destructor special is that it gets called automatically when the object is deleted. An object is deleted when the memory it occupies is freed. In the case of a dynamically allocated object (heap-allocated) using the "new" operator, the object gets deleted when you call "delete" on its pointer. In the case of a stack object (like a local variable), the object gets deleted when it goes out-of-scope (the block in which it was declared ends). So, the code you tried to write or expected to have done is:

int main() {
  {                // open a new enclosing block.
    Pig Jack;      // create a stack-based Pig object.
    Jack.Feed(20); // feed Jack the Pig.
  };               // Jack goes out-of-scope here, its destructor is automatically called.
  Jack.Feed(20);   // ERROR! 'Jack' was not declared in this scope.
  return 0;
};

Calling the destructor explicitly is not something you do normally. The destructor is always called when the object's life-time ends, but the destructor does not end the object's life-time, you just understood the causality relation in the wrong direction. Generally, an object has no control over its life-time, it is always the code (or class) that creates the object that determines when it gets destroyed (at least, that's how it should be). In C++, the code that creates the object, owns the object and is responsible for destroying it when …

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

First of all, the istream iterator gets initialized at the line 18, and so does the end iterator (default-constructed iterator marks the end).

Second, the while loop simply iterates until begin reaches the end of the input. That is what the (begin != end) condition verifies.

Third, the *begin++ dereferences the begin iterator, and increments it (for the next iteration of the while loop).

Fourth, the words[s] finds an entry in the map associated with the string "s" (or *begin++ in this case). The values associated to the strings are integers, because of the declaration std::map<std::string,int> meaning that the map associates integer values to string-valued keys. Now, if the entry does not exist (that string has not been seen before), then the [] operator of std::map will take care of creating a new entry for that string, and the integer value associated to it will be default-initialized (or zero-initialized) meaning that it will have value zero.

Then, the entry gets incremented. So, every time a string is seen it will be registered in the std::map that keeps count of the number of occurrences of every word.

Finally, the reason why the words get separated when you output them at the end of the program is because std::map keeps all the entries sorted by the key (the strings), so it will appear in alphabetical order when outputted. And the reason why you get the whole sentence when you just re-output the values of *begin++ is because …

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

@Narue:
If we were to write a holy book for Daniweb's code goddess, it would describe this moment as:

And the Narue descended from the heavens,
and with a might display of wit,
like lightning ripping the sky,
she smite down the arrogant man.
Mere mortals shall be humble before their Goddess, she said.

Now, let me humbly reply..

>>How do you figure that? [old headers not working]

I have seen them not working. On BCB6, old C file IO's don't work under Vista (I had this painful problem some years ago), while the C++ iostreams work fine.

>>They're a part of the standard, so they're required to work "fully" on any conforming implementation.

Yeah, and all compilers are _required_ to support exported templates too, but only one compiler does. All compilers and all implementations of the standard libraries are delinquent in one way or another.

>>Why? [is it bad practice to use C functions in C++]

Oh.. come on.. now you're just trying to tick me off. You don't want me to do an "Inverse Torvalds Rant", do you? First off, you could hardly argue that it is "better" to use C functions in C++ when there is an equivalent solution using C++ standard libraries, at best, the two are equal. There are a certain number of idioms and design patterns that are very desirable in C++, and I know that you know most …