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

You need to mark the dump2ivector function as const, like so:

void csv_File::dump2ivector(int column, vector<int> &data) const {....} //notice const at the end.
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>However, isn't the benefit of the shared_ptr then also nullified in a sense?

That's true, the purpose of shared_ptr is, to some extent, nullified by using a null_deleter functor. However, like many things in C++, there is a philosophy of verbosity that makes the code and intent clear. For example, in C++, static_cast is essentially equivalent to a C-style cast in most cases, but a static_cast is preferred (and explicitly preferred via compiler warnings) because it's considered better style to use a more verbose style to get rid of any ambiguity (i.e. if someone does a C-style cast, it can mean a static_cast or a reinterpret_cast, it is ambiguous and can cause silent bugs). I think you understand that already. This is why it can be preferred to use a shared_ptr, even if it means often explicitly nullifying its effect, because, in those cases, breaking the shared ownership model is explicit and intentional, it is still safer than a raw pointer.

>> the link can only be made when the object is declared

That's right. If there are ways to avoid that restriction, they are hacks that should be avoided anyways.

>>One of the conscious choices I've taken is to make use of explicit, verbose set functions, to make the code read almost like prose.

That's certainly a wise choice. My purpose of pointing alternatives out is mostly to make sure your choices are conscious and informed. Nothing is black-and-white, there are many factors to …

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

When I say "database research", I mean research being done in the field of databases and data mining. This means, professors and computer scientists who are specialists in developing algorithms to crunch massive amounts of data.

Databases are not really tied to a particular programming language. C++ is as good as any other language for dealing with databases. But, you use databases normally through client/server systems, i.e., you have a database server to which you can register data entries and perform any queries you have. You communicate to the server via a client library. Most client libraries are available in most popular languages. I'm not an expert on this, so I prefer not giving any more info on this.

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

Yeah, you are correct. You will usually not gain anything at the end by trying to force the padding to not be done (if there is a way to do so). Usually, it will be much less efficient.

If memory is really a problem, you might consider clustering several objects into one. As follows:

#include <iostream>

struct A {
  int x[sizeof(int)];
  char c[sizeof(int)];
};

int main() {
  std::cout << sizeof(A) / sizeof(int) << std::endl;
  return 0;
};

That way, each object of class A actually stores "sizeof(int)" number of records, and at the end, there won't be any padding because usually the sizeof(int) corresponds, on most systems to the alignment size. Then, to store the records, you can wrap a vector of objects of class A with a custom container that translates element access to sub-elements of the 'A' objects.

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

The subject of your question is really about what is called "data mining", which is a field of Database research. In other words, how to retrieve, classify, cluster, and compile statistics about data, especially large amounts of data. Frankly, this is what database engines are for, this is what they do, I would recommend you consider using one of those. Or, at least, read on methods for data mining in databases.

I think that for your application, the standard containers and algos don't provide enough features, and it will lead to a highly inefficient implementation, either in memory usage or in processing time. This is because you will have to either sort only according to one criteria (like date-time) and waste significant processing time to find records according to another criteria (like low-price), or you will have to have several containers to achieve fast look-ups for each criteria. What you need is a multi-indexing system, that is, you need a container which can store data once, but achieve fast look-ups for any of a number of criteria (key-value, or index). There are fundamentally three ways to do this (besides the flawed methods I just mentioned), that I know of, and I'm not an expert in this.

The first is to have one unordered container of all the data (like a std::vector or std::list) and hold several associative containers which indirectly refer to these records. This is a kind of generalization of single-index associative containers. This is implemented in …

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

>>like int occupies 2 bytes

Wow, how old is your computer? Usually, on a 32bit system, an int occupies 4 bytes (and 8 bytes on a 64bit system). For an int to occupy 2 bytes, your system must be pretty old (or very special).

>>How much memory does the reference variable occupy?

Usually, the same as a pointer. But using sizeof() on it will return the size of the type of the variable it refers to, not the size of the reference variable itself.

>>Suppose I have a structure named "person"
>>and I also have a class named "person"

Your compiler should throw a compilation error for multiple declaration of "person". In C++, there is only very trivial differences between "struct" and "class". The "struct" keyword was kept for compatibility with C, but it really wouldn't be needed since both "class" and "struct" are almost exactly the same in C++. The only trivial difference is the default access rights and default inheritance. Besides that, they are essentially interchangeable keywords. And declaring two types (whether it is struct, class, enum, typedef, whatever..) with the same name is an error, it breaks ODR (One-Definition-Rule).

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

Yeah, you should not pass large objects by value, so a const-reference is preferred to avoid the expensive copying.

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

You have to think of iterators like pointers. The idea of iterators is to mimic this C-like for-loop:

int my_array[10];  //static array;
  for(int* ptr = my_array;  //get a pointer to the start of the array.
      ptr != my_array + 10; //check that the pointer is not at the end of the array.
      ++ptr)                //increment the pointer.
    *ptr = 0;               //dereference the pointer to access the value.

The use of iterators is very similar, except that the start and end iterator are obtained with begin() and end(). So, the arithmetic (e.g. incrementing the iterator) is the same as for pointers (although iterators may not support all operations), and you need to dereference them to obtain the value at that position. So, your function could be this:

int winnerIndex(const vector<int>& list) //notice the use of const-reference, and size is not necessary.
{
	int winInd = 0;
	vector<int>::const_iterator intWinner; //if you don't modify the values, use a const_iterator.

	for (intWinner = list.begin(); intWinner != list.end();
		++intWinner)

		if (*intWinner > list[winInd])
		{
			winInd = intWinner - list.begin(); //iterator difference will give you the index.
		}

	return winInd;
}

But, actually, the C++ standard libraries have a function to find the max_element of a list, which is called like this:

int winnerIndex(const vector<int>& list) {
  return std::max_element(list.begin(), list.end()) - list.begin();
};
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

For booting, I would recommend you take and use the GRUB bootloader. Study it and figure out how to launch a kernel with it. Then, you can start making your own kernel. Start small and go incrementally.

Making an OS is definitely one of the hardest things to do. Make sure you have a well-planned idea of what exactly you want to do, and try to reuse as much as you can (for example, you should probably try to be able to reuse drivers from another OS, like Linux). You should also comply to a standard API, like POSIX.

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

>>what is most popular language to program on .net currently?

Well, that's not really related to the thread, but I would say it is C#, and then, C++/CLI. And wikipedia seems to agree with me, for what it's worth.

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

I don't know much about this subject, but I could suggest, as I often do, to consider Boost libraries. In this case, the multi-threading can be handled by Boost.Thread, and the asynchronous connections can be handled with Boost.Asio (Asynchronous IO library). As far as I know, they should be supported by as many platforms as an open-source library can.

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

Let me expand a little bit on this.

COM (or Common Object Model) is essentially a "plugin" system. There are many variations or extensions to it, but the basic principle is to have a solution for the problem of interfacing Object-Oriented code, possibly programmed in different programming languages, distributed across different modules (exe or dll), and even different computers (client-server). It is a set of standards to define how to publish a public interface of a class (in the OOP sense) with set/get functions for data members, and member functions. It is, of course, more elaborate than that, but the point is that it allows you to compile a class (referred to as Object Model) with a COM interface, and then it can be reused by other applications without recompilation or the need of header files for it. It was a nice idea and has been a largely successful project (often cited as one of the best things Microsoft ever came up with, from the point-of-view of a programmer). Today, it has a large amount of legacy code and is still used a lot, but it is a low-level thing that isn't really important for a beginner to get acquainted with (if fact, I have never learned to use it either, because it is not that important for main-stream programming). There are also many extensions to it, the most notable being ActiveX (which you have probably heard about too).

ATL is another light-weight library that simply provides ways …

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

You need some sort of use of windows API to catch keystrokes directly (including mod-states, like ctrl and shift). With win32 API, you need to make a WindowProc function and handle the WM_KEYDOWN (Windows Message - Key-down event). Then, it is just a matter of writing a big switch-case statement for the different key shortcuts. But you do need to create a window first.

Without creating a window, you might be able to use conio.h (or curses.h for Linux).

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

>>Would this be a legitimate use of raw pointers?

Ishh. Hard to tell. Raw pointers are seldom used in my code, for example. They do have legitimate uses, but it almost always falls under the hood of a library, not at the interface. In the use-case you presented, it is reasonable to use a raw pointer as a lesser-evil case, but I wouldn't go as far as saying it is a legitimate use of a raw pointer. In this case, you do want to avoid dynamic allocation whenever possible, so that's a given. You can turn a local variable into a shared_ptr by using a "null-deleter", so that is an option to comply to the shared_ptr interface while not having to have a dynamically allocated object, as so:

//define a callable null_deleter:
struct null_deleter
{
    void operator()(void const *) const
    { /* intentionally left empty */
    }
};

int main() {
  //..
  CelestialBody earth;
  CentralGravityField earthCentralGravityField;
  earth.setGravityFieldModel( 
    shared_ptr<GravityFieldModel>(&earthCentralGravityField,
                                  null_deleter()) );  
  //..
};

This simply has the effect of creating a shared_ptr that will never actually delete the pointed-to object.

But the real solution to this problem is RAII (Resource Acquisition Is Initialization), which is arguably the most powerful idiom in C++. Normally, a use-case like the one you presented would be implemented like this:

class BaseHelper {
  //some interface.. with virtual functions.
};

class DerivedHelper : public BaseHelper {
  //some overriding of the base-class interface.. and whatever else..
};

class Foo {
  private:
    BaseHelper& helper;
  public: …
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>the problem is that it alters the interface for the set and get functions in the CelestialBody class doesn't it?

Sure, it alters the interface of the set/get functions in CelestialBody, because it actually makes it a proper interface. What I mean by that is that a raw pointer (or a reference for that matter) does not convey enough information to constitute a good interface, that is why they rarely should be used unless it is obvious what they do. What is missing from a raw pointer is an indication of ownership, i.e., Who owns the object that is pointed-to by the pointer? Ownership means "who will delete it". An object can only be deleted once, no more no less, and it should only be deleted once it no longer is useful (i.e. referenced) by any part of the code. There are several ways to define ownership, mainly: unique and shared. Either you guarantee that this pointer is unique and thus can perform a delete when it is done with it (goes out of scope). Or, you have several pointers that share ownership of the object (which should be deleted once every pointer has gone out of scope). There is a third model, which is "no ownership", this means that the pointer is pointing to something that could have been deleted already by its owner(s), this is modelled with weak_ptr in C++. In any case, a raw pointer does not tell the user which of these ownership models is …

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

You are using shared_ptr the wrong way and it is causing the crash (or equivalently the "calling a pure virtual method" error). The problem is this. You are creating in 'createPredefinedCelestialBody' a shared_ptr to a GravityField object. This part is correct. The problem is that you are giving away, to the 'predefinedCelestialBody_' the raw pointer stored in the shared_ptr (via the get() function). At this point, you still have just one shared_ptr, so when 'pointerToPredefinedCentralGravityField_' goes out of scope, the reference counter goes to zero and the GravityField object gets deleted. But your 'predefinedCelestialBody_' still has a raw pointer to the object that got deleted, and thus, attempting to access it will cause a crash (or a call to a pure virtual function if you are "lucky").

The fix is simple, hold the GravityField as a shared_ptr in the 'CelestialBody' class. This way, it will work. Basically, the rule with any kind of smart pointer (auto_ptr, scoped_ptr, unique_ptr, shared_ptr, etc.) is that you should:
1) Always assign the pointer resulting from the dynamic allocation to a shared_ptr immediately (as you did in 'createPredefinedCentralGravityField').
2) Never, ever, use the underlying raw pointer for anything, this will nullify the whole point of using a smart pointer in the first place.

So, your CelestialBody class could look like this:

class CelestialBody
{
public:
    CelestialBody( ){ };

    ~CelestialBody( ){ };

    void setGravityFieldModel( shared_ptr<GravityFieldModel> pointerToGravityFieldModel )
    {
       pointerToGravityFieldModel_ =  pointerToGravityFieldModel;
    }

    shared_ptr<GravityFieldModel> getGravityFieldModel( )
    {
        return pointerToGravityFieldModel_;
    }

protected:

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

>>I need some explanation.

Yep, at compile-time, because you call the function from a base-class pointer, the base-class function prototypes are looked at, the function "print" is found, the default parameter is picked up and inserted at the call-site. In other words, it becomes:

pb->print("wtf? -.-");

Then, at run-time, the virtual dispatch is done, and thus, the overridden function is called in the derived class. Now, of course, in this simple example, the virtual dispatch will not actually happen (and be optimized away), but the "as-if" rule applies, so the behaviour is the same.

Here is another one (pretty classic): What function gets called?

#include <iostream>

struct A { };

struct B : A { };

void f(const A*) { std::cout << "f(const A*)" << std::endl; };

template <typename T>
void f(T) { std::cout << "f<T>(T)" << std::endl; };

template <>
void f(const A*) { std::cout << "f<>(const A*)" << std::endl; };

template <>
void f(const B*) { std::cout << "f<>(const B*)" << std::endl; };

template <typename T>
void f(const T*) { std::cout << "f<T>(const T*)" << std::endl; };


int main() {
  B b;
  const A* a = &b;
  f(a);
  const B* br = &b;
  f(br);
  f(&b);
  return 0;
};
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Well, you need to post the code for both classes for me to have any concrete idea as to what the problem may be.

However, due to experience, I can make a reasonable educated guess. Since the compiler should prevent you from creating an object of an abstract class, then, unless you have a very strange piece of code that somehow fools the compiler into creating an object of an abstract class, the problem must be either one of two things:
1) Calling a virtual method in a constructor (specifically, the base-class constructor where the method is 'pure').
2) Calling a virtual method in the destructor (specifically, the base-class destructor where the method is 'pure').

The Dtor/Ctor are functions in which you cannot call virtual methods (at least, not unless you know exactly what you are doing). This is because in either case the object is only half-constructor (either half-way in its construction or half-way in its destruction). This means that the virtual table is not yet fully formed until the object if fully created (and, conversely, the virtual table gets deconstructed during the destructor calls (or more precisely, it gets rolled-back)). This means that if you call a pure virtual function in a base-class constructor/destructor, the corresponding entry in the virtual table will be NULL and the program will either check for nullity (under debug mode) and give an error like the one you got, or it will not check and produce a segmentation fault …

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

Visual C++ is an Integrated Development Environment (IDE) from Microsoft to program in C++. C++ is a programming language. There are many alternatives to Visual C++ as an IDE (and compiler). Visual C++ uses the microsoft compiler (MSVC for short). As of version 2010, the Microsoft compiler is pretty much a standard-compliant C++ compiler (I couldn't say as much of earlier versions), it does include some Microsoft-specific extensions, but I don't think they should be a concern to you at this point. The most notable alternative compilers are: GCC (GNU Compiler Collection) which is free and very standard compliant (with a few extensions as well); ICC (Intel Compiler Collection) which is expensive (few thousand dollars) but highly optimized; Comeau which is not free but cheap and it is the only compiler that is entirely and strictly compliant to the C++ standard (and it is mostly used to test if code is standard, not really for production code).

An IDE is essentially a glorified text editor for coding (and many programmers just use a text editor for coding, not a full-blown IDE). Alternative options include: Code.Blocks (free); Eclipse C++ (free); Visual Studio (not free, from Microsoft, is basically an enhanced version of Visual C++, the Express edition is free, with reduced capabilities); Qt Creator (free); and KDevelop (linux-only). Just to name a few. There are plenty of threads here and elsewhere that discuss the best choices.

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

shared_ptr is currently part of TR1 (Technical Report 1), which is an extension to the C++ standard library. If you have a compiler that does not have this, then it must be very old. Read this to see how to use it. Basically, you #include <memory> and use std::tr1::shared_ptr<>. TR1 also includes other parts of Boost that are the most general purpose. Most of TR1 libraries and more of the Boost libraries will be incorporated (almost verbatim) in the upcoming C++ standard library, so, it is possible to just use the Boost libraries that will become standard, until they do, and then switch to the new standard libraries (this is what I'm doing, I have #ifdef statements to swap C++0x standard libraries for Boost libraries if the code is not being compiled on C++0x (experimental support)).

>>I've been cautious in adding external libraries

That's a very good thing. Personally, I mostly only add external dependencies in unit-test code (not library code), and if I do add an external dependency to library code, I never add it without writing a firewall to insulate it from every other part of my code (a "firewall" in programming terms is a thin wrapper library that encapsulates all the external dependency, usually via a form of the PImpl idiom (or Cheshire Cat)). But I would say that you can easily consider Boost libraries as an exception to this rule. It has awesome libraries that are mighty useful, almost every C++ programmer …

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

Well, using shared_ptr is definitely the best thing to do in this case (I use them a lot for these kind of cases). The way to have the life-time of the object under your control is to dynamically allocate it and thus, deallocate it when it should. The problem is determining when it should be deleted, and the reference counting that is part of the shared_ptr will take care of that for you, i.e., it will be deleted when it is no longer useful to any part of your code.

Don't use auto_ptr. This type of pointer will be deprecated soon because there are fundamental flaws to it with respect to the upcoming C++ standard, so it was marked as deprecated. The equivalent will be unique_ptr in C++11, the upcoming standard. But, in this case, I think shared_ptr is more appropriate (and worth the small overhead that it entails).

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

Oh ok, you didn't mention that you expect some people to be mother or father and not be also an individual (not all your parents appears as individuals, so the ID for them never gets assigned). That's the problem. A simple fix is this:

while(myfileGenealOriginal >> indivV)
  {
    STreeGen& current_indiv = IndivMap[indivV];
    current_indiv.ID = indivV; //assign ID to the new record at ID indivV.

    myfileGenealOriginal >> fatherV >> motherV;

    if(fatherV) {
      current_indiv.father = &IndivMap[fatherV];
      current_indiv.father->ID = fatherV;
    } else
      current_indiv.father = NULL;

    if(motherV) {
      current_indiv.mother = &IndivMap[motherV];
      current_indiv.mother->ID = motherV;
    } else
      current_indiv.mother = NULL;
  };

I was assuming that all parents would eventually appear as an individual somewhere (like in the input file I used).

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

What error do you get? This all seems fine to me.

I trimmed it down to bare essentials (as one should), and got this code:

#include <iostream>
#include <fstream>
#include <vector>
#include <map>

struct STreeGen                      /* Family structure declaration   */
{
  int ID;
  STreeGen *father;         /* Pointer to father structure   */
  STreeGen *mother;         /* Pointer to mother structure   */
} ;


int main()
{
	int indivV = 0;
	int fatherV =0;
	int motherV = 0;

	std::ifstream myfileGenealOriginal;

	myfileGenealOriginal.open("ped.txt");

	// ----------------------------
	std::map<int, STreeGen> IndivMap;
	// ----------------------------

	while(myfileGenealOriginal >> indivV)
	{
		STreeGen& current_indiv = IndivMap[indivV];
		current_indiv.ID = indivV; //assign ID to the new record at ID indivV.

		myfileGenealOriginal >> fatherV >> motherV;

		current_indiv.father = ( fatherV ? &IndivMap[fatherV] : NULL );
		current_indiv.mother = ( motherV ? &IndivMap[motherV] : NULL );
	};

	std::cout << "PRINTING:" << std::endl;

	std::map<int, STreeGen>::const_iterator it;
	for (it = IndivMap.begin(); it != IndivMap.end(); ++it)
		std::cout << it->first << '\t' 
                          << (it->second.father ? it->second.father->ID : 0) << " " 
                          << (it->second.mother ? it->second.mother->ID : 0) << std::endl;

   return 0;
}

I tested it with the input file:

5 0 0
3 6 7
6 0 0
2 4 5
7 0 0
1 2 3
8 0 0
4 0 8

And it printed out:

PRINTING:
1       2 3
2       4 5
3       6 7
4       0 8
5       0 0
6       0 0
7       0 0
8       0 0

As expected. I don't see any problems..

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

The problem is this line:

return insert_comma_helper(
           integer.substr(0, size - 3),
           result = integer.substr(size - 3, 3) + ',' + result);

The reason why tail recursion is not done in this case is because you have temporary string variables in your recursive function call. That is the main difference between the two code snippets (the first only has integer temporaries). This makes a big difference because the std::string requires destruction, which will be executed just _after_ the return-statement, rendering tail-recursion impossible.

There are certainly ways in which you could allow tail-recursion in this case. The main idea is that all things that are not part of the parameter list or of primitive types should be already destructed (or not created yet) at the point of the return-statements. This can often be implemented using scopes and adding working variables as parameters to the function (which is OK most of the time since you usually write a recursive function as a local function (like you did) or some other form of "hidden" helper function, and thus, it doesn't affect the actual interface function that a user would call). With that in mind, I would think that this solution might have a much better chance of qualifying as a tail-recursion:

//here, I break const-correctness, but it does no harm since the function is
// local (the original "integer" can be copied by caller), and this gives 
// you a free string variable that doesn't ever get destructed in all recursions. …
m4ster_r0shi commented: very interesting, thanx +1
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

I think you are going about this the wrong way. You should first think logically about what your program will have to do. Here is what I would say your program needs to do (at high level):

1) Read the IDs of the individual, and parents.
2) Create a record for the individual.
3) Find the records of the parents and link them to the individual's record.

Now, you have the reading part done correctly, although, this might be simpler:

while(myfileGenealOriginal >> indivV) {
    myfileGenealOriginal >> fatherV >> motherV;
  
    //do step 2 and 3 here.
  };

Then, you did step 2 correctly, in some sense, but now you are stuck at step 3 because you didn't do step 2 in a way that would facilitate step 3. In C++, you have many choices of containers, including associative containers which allow you to associate a key-value to each record. In this case, the most appropriate container for your individual records would probably be std::map. This container will allow you to be able to look-up individuals based on their ID directly and efficiently. Furthermore, if you look-up an ID that doesn't exist, then it will be created. This is perfect because it allows you to do step 2 and 3 at the same time. For example:

map<int, STreeGen> IndivMap;
  while(myfileGenealOriginal >> indivV) {
    STreeGen& current_indiv = IndivMap[indivV];
    current_indiv.indiv = indivV; //assign ID to the new record at ID indivV.

    myfileGenealOriginal >> fatherV >> motherV; …
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Is this the Java forum? I'm confused... no, it is the C++ forum. Please post your code in the appropriate programming language for the forum!

Whatever Random is, I assume it is a class that you wrote or your prof gave you as part of the assignment, because it is not part of C++ standard libraries (I just wanted to point that out because there are many clues in your code that suggest you are a Java programmer). To generate random numbers in C++, you can use rand() (and srand() to seed it), or any random number generator for the <random> library (may not yet be supported by your compiler, it is from the upcoming C++ standard).

The "Fatal Error" is due to either the fact that most C/C++ compilers require an empty line at the end of the code (so you need to leave at least one empty line at the end), or it is due to the fact that you don't have a main() function. The main() function you have is a static member function. This is not C++ (it is Java). A main function in C/C++ is like so:

//free-function
int main() { //must return a value of type 'int'
  //insert code here..
  return 0; //return 0 if all went well, otherwise return an error-code of your choice.
}

//the other alternative is to capture the command-line arguments as well:
//int main(int argc, char** argv) {

Second, you shouldn't have a default constructor that …

NathanOliver commented: Very well done. To bad we can only add once :) +9
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>I shall not fear any optimisation surprise?

Do not fear. You are 100% guaranteed that if you have two base pointers which are identical (same address), then they point to the same object. And when I say 100%, I don't mean 99.999%, I mean 100%.

What you might/could/should fear, depending on the complexity of your class hierarchy, is the opposite case. That is, if you use multiple inheritance and don't use also virtual inheritance, you could have the problem that two base pointers which are different actual point to the same object. Read this to know why.

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

>>does the C++ standard permits a C++ compiler/optimiser to use a sort of "copy on write" optimisation for the specific case I mentionned?

No. C++ implements value-semantics. This means that two different objects can never be two references to the same object. You can, of course, have two references or pointers to the same object, but that is entirely under your control, the compiler has little to do with that.

There are certain optimizations that the compilers are allowed to do when it comes to base versus derived class pointers. That is, if you hold a pointer to a base-class object, but the context makes it obvious to the compiler that the object is of a particular derived class, the compiler is allowed to by-pass the virtual function call and make an ordinary function call to the function it knows will be called anyways via the virtual dispatch mechanism. For example, a trivial case:

#include <iostream>

struct B {
  virtual void print() const = 0;
};

struct D : B {
  virtual void print() const { std::cout << "Hello World!" << std::endl; };
};

int main() {
  D d1;
  B* b1 = &d1;
  b1->print(); //here, the compiler will most likely by-pass the virtual table look-up because it is clear from the context that b1 actually points to an object of class 'D', and so, it can call D::print() directly.
  return 0;
};

You can try the above and output the assembly listing for it and you will …

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

I think you are very confused, no offence. It seems you don't understand the difference between an object and a class. An object is an instance of a class, in other words, the class is the type, and an object is a variable of that type. So, if you have two pointers to two objects, they will never be equal even if they are of the same class, because they point to two different instances (or objects) which are at different locations in the memory (and thus, have different addresses). So, that fact just nullifies your question completely.

If this was not what you meant by your questions, please rephrase and provide a bit of code to illustrate the class hierarchy and use-case you are talking about.

N.B: if you want to compare two pointers, you have to use two equal signs
"==", not one (that is an assignment operator).

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

Just adding my grain of salt here. Disclaimer: these are all just my humble opinion...

Personally, I use KDevelop. I find it to be awesome. The code highlighting is pleasant to the eye, the background parsing is fast, and code completion works very well. It is also fully integrated with gdb (for debugging). And it supports most build systems like makefiles and cmake. It is also integrated with Qt designer so that you can make GUIs with Qt Designer and code on them with KDevelop. I also highly recommend you get used to using an independent build system (non IDE-bound), and cmake is very nice for that (and cross-platform). I highly recommend KDevelop as an IDE, I have not found a parallel to it (commercial or free, Linux or Windows). On windows, I default to CodeBlocks which I think is also pretty good.

For the others, I have used most of them in the past as well.

Linux/Windows:
- Code.Blocks: As I said, it is nice. I like the fact that it has few "automatic" BS that gets in the way of coding. However, I think it has poor integration with third party software (external build systems, debuggers, GUI tools, etc.). I also find that the code completion (and background parser) is too slow to be useful, I usually turn it off, since I can type faster than it can come up with code completion suggestions.
- Eclipse: I have used the Java IDE for …

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

far and near are reserved keywords in C (not standard, but common, it is a relic from the times of 16bit architectures), it is generally not present in C++, but it's possible that your particular compiler uses it in C++ for compatibility with C. That's the only explanation I can think of.

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

None of them are built into C++. However, the Boost library is almost like the standard C++ library (Boost is often called the anti-chamber of the C++ standard libraries, for example, most of the new standard libraries in the upcoming C++ standard are taken directly from Boost, almost verbatim). This is you safest bet as a care-free add-on to your code. You do need to install it though. If you use Linux or Mac, this is very easy, just get the latest stable version from your package management system (e.g. Linux: $ sudo apt-get install libboost-all-dev), and that's it. If you use windows, then you have to download the latest distribution from Boost and install manually. To use the uBLAS library you will not need to build and link anything (it's a header-only library), so it's just a matter of adding the Boost install directory to your project's include paths, and you are good to go. At that point, all you need is to follow the instructions on how to use the various parts of the library and #include the headers that they say you need to include.

Blitz++ is not recommended unless you have very good knowledge of C++ (and it is not the most feature-rich library either, although it is very efficient).

My own library is somewhat experimental (and linear algebra is not the focus of it), and is also not recommended unless you have very good knowledge of C++ (and it does require a little …

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

Just a thought:

>>I am building a library of matrix and vector operations.

>>then I must write a function for each of those operations.

It seems odd to me that you are building a library for matrix and vector operations and you are complaining that you need to write all the operations. Isn't that what "building a library for matrix and vector operations" mean?

Furthermore, it seems odd that you want to perform all these element-wise operations... that doesn't really make sense in vector/matrix/tensor algebra. If someone takes the square root of a matrix, the normal semantics for a square root operation on a matrix is certainly not an element-wise operations (more like a Cholesky decomp or something more general).

Also, you have to watch out with the use of typedefs. Remember that typedefs are not new types, they are just an alias for a type name. So, if you define your own operator like log( Mat ), and Mat is a typedef for valarray<Vec>, it will be ambiguous with the std::log version for std::valarray. Additionally, you should not import the std namespace in a header, I mean, you really should NOT do that. And you should also create your own namespace for your library too.

Final thought, don't reinvent the wheel, use a matrix library off-the-shelf. Like Blitz++, Boost.uBLAS, or mine (ReaK.math).

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

"pow(e,2*pi*j/n)" is a complex number with magnitude 1 and angle 2*pi/n. You just need to create that number, and thus, I reiterate my solution:

complex<double> w = polar(1.0, 2*pi/n);
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>How are the programs made so that they run with GUI interface and stuff like that?

GUIs are made through the use of external libraries (either OS APIs or other (cross-platform) GUI libraries).

Usually it is not really recommended to start making GUI applications until you have a pretty good grasp of OOP, since most GUI libraries are object-oriented and rely heavily on things like pointers, inheritance, polymorphism, abstract interfaces, event-driven software, etc. However most OS APIs and some simple GUI libraries use what is essentially a collection of C-style functions, but they are generally much harder to use (as in, it makes you write a lot of code, in a painful way).

Qt is a free GUI toolkit that is very good and cross-platform (but there are others like MFC, WinForm, wxWidget, VCL/CLX, etc.). I would recommend starting with Qt. If it turns out that it seems too complex, then maybe you will have to wait some more to get a more solid grounding in OOP and C++ (none of the other GUI tools will be any easier). Just follow online tutorials and start from there.

>>Are they exported differently

As for integrating console-program code into a GUI, it is mostly a matter of implementing the event-handlers (code that executes when the user does something, like clicking a button or menu). Implementing the event-handler is basically just normal C++ coding (include the headers you need, and code). The second difference is that …

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

You don't have to use the letter 'i' for every for-loop variable. In fact, you shouldn't do that. You can pick any variable name you like, although it is idiomatic to use i,j,k,l.. letters, but that is just a convention. What you should not do is have several nested for-loops with the same variable name, this will be, at best, very confusing and, at worst, erroneous.

In any case, I see no reason to have nested loops here. That code makes no sense.

Also, your structure in which you hold the records is very weird. You have an array of names and brands for the products, but a single value for the rest. That makes no sense, at the end you will only have the last inputted set of values, because your inventory only stores one set of values. I would suggest having a structure for one item or product and then keeping an array of products. Maybe like so:

struct Product {
  string name;
  string brand;
  int stock;
  float price;
  //.. whatever else..
};

int main() {
  const size_t inventory_size = 10;
  Product inventory[inventory_size]; //keep an array of products as an inventory.

  //...
};
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Well, I think you need to brush-up on some complex algebra stuff...

With Euler's identity, this e to the power of 2*Pi*j/n is simply a rotation by 2*Pi/n. You can easily construct this complex number by using the "polar" function, as so:

w = polar(1.0, 2*pi/n);
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>Other languages try to realize matrix data manipulation in correspondence with matrix theory. c++ is a little bit odd in this regard.

Well, C++ does not try to realize matrix data manipulation at all. So, it is not surprising if it seems odd to you. Languages like Fortran and Matlab are two examples of languages which were built with the explicit intent of realizing matrix operations naturally (Fortran did not succeed much in that regard, although it is used a lot and has many legacy and well-optimized code for numerical analysis in general). But, you pay for everything in programming. Matlab is very nice, natural and optimized for doing matrix operations, but it quickly gets awkward when you move away from matrix numerical analysis. C++ is probably the most universal programming language, which also means that it has to please a whole lot of people doing many different things. And not everyone is doing matrix operations, or numerical analysis, or anything related to math for that matter. If you try to provide nice built-in features to please everyone, you end-up pleasing no-one (e.g. Java). The approach in C++ is to provide only the most incontestably useful functionality in its standard libraries and then provide unparalleled language features to allow the development of awesome libraries for special purposes.

And so, to the point, there are plenty of nice open-source libraries for matrix operations. They range from very easy-to-use (often resembling Matlab) to extremely optimized and robust (often old cryptic …

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

What Walt means is that the format in which you are getting the time string from strftime() is not the only one you can get. The string that is given to the function, i.e., "%d%m%Y%H%M%S", is what specifies how you want your date and time to look like in the string. Simply change that string to something else, according to the this table.

For instance, the format you described would be obtained with "%x %X", which would give you "16/06/2011 01:13:00".

If you absolutely want to do the conversion manually, it is trivial since the number of characters is fixed. As so:

DLL_EXPORT char* ConvertTimestamp(const char* t_in) {
  static char t_out[20];
  t_out[0] = t_in[0]; t_out[1] = t_in[1];
  t_out[2] = '/';
  t_out[3] = t_in[2]; t_out[4] = t_in[3];
  t_out[5] = '/';
  t_out[6] = t_in[4]; t_out[7] = t_in[5];
  t_out[8] = t_in[6]; t_out[9] = t_in[7];
  t_out[10] = ' ';
  t_out[11] = t_in[8]; t_out[12] = t_in[9];
  t_out[13] = ':';
  t_out[14] = t_in[10]; t_out[15] = t_in[11];
  t_out[16] = ':';
  t_out[17] = t_in[12]; t_out[18] = t_in[13];
  t_out[19] = '\0';
  return t_out;
};

N.B.: It is not recommended in general to send a pointer to static data as the return value of a function like this. It is not dangerous or erroneous, it is simply not nice because someone can easily be fooled into thinking that he needs to free that memory or use it as if he was allowed to. I know that this is C-style code, and thus, it limits what …

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

Read the documentation carefully. For instance, under glTexCoordPointer, you will find:

If a non-zero named buffer object is bound to the GL_ARRAY_BUFFER target (see glBindBuffer) while a texture coordinate array is specified, pointer is treated as a byte offset into the buffer object's data store.

In plain english, it means that the last parameter to glTexCoordPointer is treated not as a pointer (even though that is its type) but as an offset from the start of the array in the buffer that is currently bound (in your case, the 'model' buffer).

And:

To enable and disable a texture coordinate array, call glEnableClientState and glDisableClientState with the argument GL_TEXTURE_COORD_ARRAY.

And:

glTexCoordPointer updates the texture coordinate array state of the active client texture unit, specified with glClientActiveTexture.

glInterleavedArrays is also an option.

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

I was just illustrating the idea. When I throw together a piece of code in 5 min. to illustrate "how to" fix it, don't expect the code to compile directly, you have to use your own wits too. I guess you would have to define the last parameters to the gl**Pointer() functions as so for example:

glTexCoordPointer(2, GL_FLOAT, sizeof(VertDef), 
      (char*)(NULL) + sizeof(float) * (&(vars[0].t[0]) - &(vars[0].v[0])));
    glNormalPointer(GL_FLOAT, sizeof(VertDef), 
      (char*)(NULL) + sizeof(float) * (&(vars[0].n[0]) - &(vars[0].v[0])));

The above doesn't fundamentally change anything, this was just a small omission on my part, you should learn to fix those kinds of trivial problems on your own, otherwise you will have a long way to go.

BTW: "it seems we are using different headers" ... I am not "using" anything, I'm not compiling your stuff and trying it out, nor did I do that with the code I posted, I'm just suggesting fixes and improvements, you're the one who has to do 99% of the work. Which includes reading all the required resources, and being able to fix small issues like this one by yourself.

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

There are several things wrong with your code.

First, you have completely redundant pieces of code that clearly abuse dynamic memory allocation. As in this snippet:

float *temp=new float[numv*5];
    for (int i=0; i<numv*5; i++)
        temp[i]=vars[i];
    delete[]vars;vars=NULL;
    vars=new float[numv*5+5];
    for (int i=0; i<numv*5; i++)
        vars[i]=temp[i];
    delete[]temp;temp=NULL;

You allocate, copy, delete, allocate, copy and delete. One of those repetition is useless. Here is the proper way to do it:

float *temp=new float[numv*5 + 5]; //allocate with new size.
    for (int i=0; i<numv*5; i++)
        temp[i]=vars[i];               //copy.
    delete[]vars;vars=NULL;            //delete old data.
    vars = temp;                       //swap pointers.
    //then, fill the values of the new element.

Additionally, the use of a C-style array is very inefficient. You should use std::vector instead, or, at least, preallocate enough memory ahead of time.

Secondly, in Compile(), you don't need to build two new arrays for the vertices and tex-coords that are already interleaved in your "vars" array. OpenGL already has functionality to handle this kind of interleaved arrays (which is standard practice too). This is handled using the "stride" parameter in all the functions. So, all you need in Compile() to send your vertices and tex-coords is the following:

glGenBuffers(1,&model);
    glBindBuffer(GL_ARRAY_BUFFER, model);
    glBufferData(GL_ARRAY_BUFFER, numv * 5 * sizeof(float), vars, GL_STATIC_DRAW); //notice '5' and 'vars'

And then, in your Draw() function, you can simply do:

glBindBuffer(GL_ARRAY_BUFFER, model);
    glVertexPointer(3, GL_FLOAT, 5 * sizeof(float), 0);
    glTexCoordPointer(2, GL_FLOAT, 5 * sizeof(float), 3 * sizeof(float) );

The last two parameters first tell OpenGL to skip 5 floats between …

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

**Please clean your code and use correct indentation when posting**

Your teacher is correct. I don't really understand your question.

First, unless you need a take the original string and turn all the letters into upper-case, I see no reason why you would need more than one string for this whole program. For instance, you can count the letter occurrences this way:

int tot = 0, alpha[26];
  
  for(int i = 0 ; i < 26 ; i++)
    alpha[i] = 0;
  
  cout << "Please enter a text: " << endl;
  getline(cin, txt);
  cout << "\n";

  for (int pos = 0 ; pos < txt.length() ; pos++)
  {
    char tmp_c = toupper(txt[pos]); //use a temporary that is only upper-case.
    if(tmp_c >= 'A' && tmp_c <= 'Z') {
      alpha[ tmp_c - 'A' ]++; //use 'A' instead of 65, it is less confusing this way.
      tot++; //why not increase 'tot' at the same time..
    };
  };

The way you "ignore spaces and punctuations" is by simply skipping them as you traverse the string. In other words, instead of incrementing the index by 1 at every iteration, you increment it enough to find the next letter character. As, for example, if you want to print only the letter characters, you could do:

for( int i = 0; i < txt.length(); i++ ) {
    char tmp_c = toupper( txt[i] );
    while(tmp_c < 'A' || tmp_c > 'Z')
      tmp_c = toupper( txt[++i] );
    cout << txt[i];
  };
  cout << endl;

Finally, for the …

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

@ravenous, I totally agree. The need for a forward-declaration (from having circular dependencies) is usually indicative of some fundamental design flaw (i.e. not splitting responsibilities correctly leads to awkward dependencies, circular dependencies and/or too many dependencies). But you are right, aside from the purpose of resolving circular referencing problems, forward-declarations can be very useful to minimize the trail of header-file inclusions and thus reducing build times. Similarly, the Cheshire Cat idiom (or PImpl) uses forward-declarations to tuck away a dependency relating to the details of an implementation into the cpp, and thus, achieving a compilation firewall which is also very useful to minimize the needs for recompilation of source code.

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

When doing malloc(sizeof(btree)); , you are allocating enough memory to store a pointer to a node (that is was btree is, just a pointer to a node, not a node). That does not, in any way, allocate any memory to store the node content. When you are later accessing the node that this new pointer is pointing to (which is nowhere, btw), you are just corrupting your memory, big time. One annoying thing with memory corruption problems is that the error messages you get are typically unrelated to the error itself. When you corrupt memory, it can corrupt almost any kind of memory, including the heap itself, other memory in the heap, stack memory, executable code, and the list goes on. And you are not even always guaranteed that it will crash, but usually it does, and when it crashes, it is not the corrupting (or faulty) code that crashes but the code which is affected by the corruption, which often has very little to do with the faulty code. So, conclusion, as Narue said, "It's caused by something else.".

But, of course, your code in the crear_nodo() function is a blatant memory corruption, so, I would start by fixing that, and then revisiting all your code for similar memory corruption problems. Here is a more reasonable version of it:

btree* crear_nodo(btree* r, int dato){
    *r= (nodo*) malloc( sizeof(nodo) ); //notice sizeof(nodo)
    (*r)->clave[0]=dato;
    (*r)->clave[1]=NULL;
    (*r)->clave[2]=NULL;
    (*r)->rama[0]=NULL;
    (*r)->rama[1]=NULL;
    (*r)->rama[2]=NULL;
    (*r)->peso=1;  
    (*r)->color=0;
    return r;
}

Another important aspect is, you …

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

This "pre-declared class", as you call it, is what programmers call a "forward-declaration". A forward-declaration is useful when you need two classes to depend on each other (which would otherwise not be possible). Here is a simple example:

struct DogOwner {
  Dog fido;
};

struct Dog {
  DogOwner master;
};

Obviously, the above won't work because to declare DogOwner, you need Dog to be declared, but to declare Dog, you need DogOwner to be declared. This is called circular referencing (like circular logic), it simply cannot work that way. Forward-declarations offer a solution to this, as follows:

struct DogOwner; //forward-declare DogOwner

struct Dog {
  DogOwner* master; //note that a forward-declared class can only be held by pointer or reference.
};

struct DogOwner {
  Dog fido;  //this works!
};

What a forward-declaration does is simply to give a promise to the compiler that there will be a real declaration of that class later on in the source code. This way, you can declare pointer and references to objects of that class before the compiler actually sees the declaration of that class (but, you cannot use objects of that class, only references and pointers).

So, the reason why you have this forward-declaration of Mesh in the code you posted is most likely because Mesh also needs the declaration of Equation.

Additional note: most of the time forward-declarations are avoidable and are often an indication of poor design of the software. So, be cautious in using them, explore other …

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

>>I guess it has just monitored hundreds of thousands of games and returns the best statistically winning move (given the previous moves).

Not exactly. Such gross statistics are not good enough in general. As I said earlier, they typically do an online estimation of a Hidden Markov Model (HMM). The hidden state is representative of the "state of mind" of the player (usually modeled by some vector of numbers that is large enough to account for the complexity of the decisions involved). Then, the result of the previous game (the computer's move) will modify the state of mind of the player, and that next state of mind will determine (with some probability) the most likely next move. The job of the computer which is doing the learning is to try and determine the two relationships involved: the state transition function and the state-output function. In other words, the learning algorithm has to try, based on enough evidence, to estimate how his previous move causes a state transition in the human player's state of mind, and then has to estimate how a particular state of mind translates to probabilities of an output (next move by the player). Standard algorithms for this are typically classified as EM (Expectation Maximization) which is a kind of double-step algorithm (like predictor-corrector algorithms), the best and simplest example of which is the Viterby algorithm (which is a dynamic programming version of EM). The idea is usually to assume a …

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

Your code is valid, but it does nothing. You have the following in your code:
- Declaration of a union type called 'un' (lines 1 to 6).
- Declaration of a global variable called 'u1' of type 'un' (line 6).
- Declaration of a global pointer called 'up' which is initialized to point to 'u1' (line 7).
- Declaration of a function called 'randomFunctionName' which takes a pointer to 'un' as a parameter and internally calls it 'up' (which hides the global variable 'up') (line 8).
- Definition of the function called 'randomFunctionName' (line 9 to 11).

You can notice from the list above that there is nothing other than declarations and a function definition. You have no main() function which would actually start the execution of any kind of code, and you have not called the function 'randomFunctionName' anywhere either. Don't be surprised if this does not accomplish anything.

To fill in the bits that are missing:

#include <iostream>

union un {
  bool a;
  int b;
  char etc;
};

void randomFunctionName(un* up) {
  up->a = true;
};

int main() {
  un u1; //create a local variable called 'u1'
  randomFunctionName( &u1 ); //call the function giving it the address of 'u1'
  std::cout << "u1 is now " << u1.a << std::endl;
  return 0;
};
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>but seeing as the decisions are totally random and winning is down to pure luck

@iamthwee: You are making the strong assumption that humans playing rock-paper-scissors are actually making random choices. That is demonstrably false. Humans are no better at generating random numbers than computers, in fact, they are much worse. Humans are not truly capable of coming up with a random pick, there is always an underlying logic or strategy (even in situations where a strategy is meaningless), we simply cannot "compute" the pick any other way. This is a well known fact, especially in the realm of mentalism (magic (or illusionism) based on mental tricks), for instance, if you ask a person for an arbitrary number between 1 and 100, you have about 40% chance that the number picked will be 37 because even if nothing makes one number more random than another, we, humans, in that situation, tend to not go for certain numbers that don't seem random enough to us (like all even numbers, all numbers below 20 or so, all the numbers that appear in multiplication tables we learned as a child, etc.), and the result by elimination and not going to far in the high numbers is 37. Similarly, many mentalists use "suggestion" which just means that they say a few innocent- and inconsequential-sounding things before they ask you to pick a card or make drawing, but that is enough to suggest to your mind to pick a particular logic that leads to …

iamthwee commented: nice +15
tux4life commented: Solid post. +13
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

You are not allowed to overload an operator for a built-in type (int, float, double, char, etc.). So, if your operator overload only involves built-in types, even if that operator doesn't exist yet for that type, it is illegal to do so. This is just a safe-guard built into C++ to stop people from doing crazy things like redefining existing operators and giving them different semantics (and also, for technical reasons, such as overload resolution when built-in types don't reside in any namespace).

Just use a regular function with a name. Operator overloading is just syntactic sugar, don't abuse the feature, use it only when it fits very naturally and when the semantics are either completely analog to the "normal" use of the operator or when it is idiomatic (as in the << operator for ostreams in C++).