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

First of all, the iostream library is already buffered under-the-hood. So, there isn't much reason for you to add another buffer on top of that (although it might help). The reason for your slow performance with this line:

flowC << prevsid << ", " << threadid << endl;

is in part due to ascii output (or formatted output), but mainly due to the presence of endl at the end of the output. The endl thing has two effects: adds a new-line to the output; and flushes the stream. The latter effect means that everything that is currently pending on the stream's internal buffer will be flushed, i.e., physically written to the file. So, the main problem here is that you are flushing the buffer every time in that loop. Simply replacing the endl with a new-line character will make a big difference because the stream will essentially do exactly the kind of buffering you were trying to do yourself (write stuff to a temporary buffer until it is too full and then flush it to the file). So, try this instead:

flowC << prevsid << ", " << threadid << "\n";

If you actually want to do some buffering on your own, on top of the buffering that is already done by the file-stream object, then I would recommend that you use a std::stringstream instead. As follows:

std::stringstream ss_buffer;

.......

  // in the loop:
  ss_buffer << prevsid << ", " << threadid << …
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

To your previous problem, I don't really know what is going on. But I would generally recommend that you don't use only one file-stream for reading and writing. I think that is where the problems might be coming from. Generally, you should use a ofstream for output operations, and ifstream for the input operations. You probably should go about it something like this:

  • Keep all the records (dInfo) in a vector.
  • When asked to save all the records to a file, then,

    • Open the file using a ofstream, with flags ios::binary | ios::out.
    • Write the entire vector of records into the file.
  • When asekd to load all the records from a file, then,

    • Open the file using a ifstream, with flags ios::binary | ios::in.
    • Clear the current vector of records (or keep it temporarily).
    • Read all the records from the file into a vector.
    • (Merge the vector of records from the file with the pre-existing record vector, eliminating duplicates).

That's going to be easier the manage. Then, all your other operations can be done on that vector of records (not through constantly reading and writing to a file). Also, using the input-stream for inputs and the output-stream for outputs will give you a better chance at avoiding the issues you have with the end-of-file marker and stuff.

It's got the period between dInfo and push_back underlined and is saying:

If you look at the reference website for push_back(), you'll see that, …

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

The solution to your problem is to use dynamic loading of the DLL. Look at the functions: LoadLibrary(), GetProcAddress(), and FreeLibrary(). This is basically the way that you can programmatically call a function (LoadLibrary) to load the DLL, then make calls to the GetProcAddress function to obtain function pointers to individual functions within the DLL, and then, once you are completely finished using the DLL, you can call FreeLibrary to un-load the DLL. This is, of course, a lot more trouble than doing it statically (the traditional way, where it gets loaded before you even start the main() function) because you have to manually assign all the function pointers via calls to GetProcAddress.

Another solution is to create a module of your own (a DLL) that has all the code that uses that DLL, but exposes fewer functions. Then, that new module would load the DLL in question statically (as usual), but be loaded dynamically by your main application. This way, you avoid having to dynamically load the external DLL, if that DLL has a lot of functions to be loaded from it, and you can still catch the error about the missing DLL.

N.B.: Under Unix/Linux/MacOSX systems, the equivalent functions to LoadLibrary / GetProcAddress / FreeLibrary are dlopen() / dlsym() / dlclose(), respectively.

Can you please explain what is /MT and how to enabled it ?

The /MT is a command-line option for the MSVC (microsoft visual C++) compiler …

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

Chop your own wood, it'll warm you twice.
-- Henry Ford

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

Oh, sorry, it should be istream and ostream, instead of ifstream and ofstream. That should fix it.

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

Just curious.. what compiler did you use? I just like to keep tabs of these kinds of compiler-specific issues.

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

I have a some libraries which have a lot of common classes but the namespaces are different. Most of the code I was writing could be easily reused by classes in both libraries so after some reading I tried a technique of using the templates to pass namespace.

That is a very ugly and awkward technique. I can think of a thousand better ways of achieving the same effect. One typical way is using a tag dispatching mechanism with meta-functions, as so:

struct dummy_type { };

template <typename Tag>
struct get_T1 { typedef dummy_type type; };

template <typename Tag>
struct get_T2 { typedef dummy_type type; };


namespace A {

    class T1 {
        public:
            int i;
    };

    class T2 {
        public:
            int x;
    };

};

struct A_tag { };

template <> struct get_T1<A_tag> { typedef A::T1 type; };
template <> struct get_T2<A_tag> { typedef A::T2 type; };


namespace B {

    class T1 {
        public:
            int i;
    };

};

struct B_tag { };

template <> struct get_T1<B_tag> { typedef B::T1 type; };


template <typename Tag>
class util{
    public:
        void print(const typename get_T1<Tag>::type& tobj)
        {
            std::cout << tobj.i << std::endl;
        }

        void print2(const typename get_T2<Tag>::type& tobj) {
            std::cout << tobj.x << std::endl;
        }
};

The above is a lot more elegant because you can declare, alongside your namespace declaration, what types you want to "expose" via a given "tag". You can even make a specialization for the meta-function (e.g., get_T1 and get_T2) to trigger a compile-time error if instantiated. …

Agni commented: Thanks for the alternate technique +8
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

You cannot use this type of thing:

movieFile.read(reinterpret_cast<char *>(&thisDVD), sizeof(thisDVD));

this is bad. You cannot just dump the memory of "thisDVD" into a file like that. You need to create a member function in the DvdInfo class that will save / load the file by saving individual data members. Something like this:

class DvdInfo {
  // ....

  void saveToFile(ofstream& OutStream) {
    OutStream.write(reinterpret_cast<const char*>(thisMovie.sTitle), strlen(thisMovie.sTitle) + 1);  // the '+ 1' is for the null-termination character.
    OutStream.write(reinterpret_cast<const char*>(thisMovie.sA1), strlen(thisMovie.sA1) + 1);  // the '+ 1' is for the null-termination character.
    OutStream.write(reinterpret_cast<const char*>(thisMovie.sA2), strlen(thisMovie.sA2) + 1);  // the '+ 1' is for the null-termination character.

    OutStream.write(reinterpret_cast<const char*>(&thisMovie.sYear),sizeof(int));
    OutStream.write(reinterpret_cast<const char*>(&thisMovie.sTime),sizeof(int));

    // ...
  };

  void loadFromFile(ifstream& InStream) {
    InStream.getline(thisMovie.sTitle, 126, '\0');
    InStream.getline(thisMovie.sA1, 80, '\0');
    InStream.getline(thisMovie.sA2, 80, '\0');

    InStream.read(reinterpret_cast<const char*>(&thisMovie.sYear),sizeof(int));
    InStream.read(reinterpret_cast<const char*>(&thisMovie.sTime),sizeof(int));

    // ...
  };

};

But, in general, I recommend saving and loading into a text format (not binary), because it's less trouble that way (and you can open the file in a text editor to see what it produced). And, of course, you call the save-load functions like this:

switch (mChoice)
    {
    case 1:
            thisDVD.loadFromFile(movieFile);
            while(!movieFile.eof())
            {
                cout << thisDVD.sTitle << " (" << thisDVD.sYear << ")" << endl;
                cout << "Starring " << thisDVD.sA1 << " and " << thisDVD.sA2 << endl;
                cout << thisDVD.sTime << " minutes" << endl;

                thisDVD.loadFromFile(movieFile);
            }
        break;
    case 2:
        if (dInfo.setInfo())
        {
            cout << "\n\nSaving the DVD information to the file..." << endl;
            thisDVD = dInfo.passInfo();
            thisDVD.saveToFile(movieFile);
        }
        break;
    case 3: …
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

There is a conflict between your declaration of the struct Movie in the main file and in the DvdInfo class. I would recommend that you move the struct Movie declaration out of the DvdInfo class to just above it (still in the dvdinfo.h header). And remove the declaration in main file. As so:

#ifndef DVDINFO_H
#define DVDINFO_H

#include<string>
using namespace std;

struct Movie
{
    string sTitle, sA1, sA2;
    int sYear, sTime;
};

class DvdInfo
{
private:
    static int dvdCount;

    Movie thisMovie;
    bool isCorrect, doSave;
    char yesno;
public:
    // ....
};

#endif

and the main file:

#include "dvdinfo.h"
#include<iostream>
#include<string>
#include<fstream>
using namespace std;

void displayMenu();
void mFileIn();

int main ()
{
//...
//...    

The above fix will solve your problem about thisDVD = dInfo.passInfo();.

As for the error in setInfo() about cin and cout, that error is just because you have not included the <iostream> header in your dvdinfo.h header file. So, you need this:

#ifndef DVDINFO_H
#define DVDINFO_H

#include <string>
#include <iostream>   // notice addition here.
using namespace std;

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

The difference in total memory used between a vector or an array is going to be negligible (probably only one pointer and two integers).

The use of a vector is going to take a bit more time to allocate the memory because it must ask the heap to allocate a chunk of memory. But that's about it.

If you use a static array, it will be a faster because it is allocated on the stack. However, the stack has only a limited amount of memory available (usually 2 or 8 Mb), so, it is not really a good idea to take too much of the stack memory for large arrays. Every time you call a function, the local variables are allocated on the stack, taking up more and more of the stack memory, and so, that is why a recursive algorithm can end up running out of stack memory (called a "stack overflow").

In summary, the overhead of allocating the memory dynamically (using std::vector) is slightly more than using a static array, but it is usually negligible compared to whatever else you actually do with the elements in the array. And because you should avoid using the stack too much, it is usually better to use a std::vector for an array of any significant size.

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

You can use the "Widget" object, and a lay out. It's kind of hard to explain how to do this, but it is easy.

Say you have a main window. You can create a Widget that you put on it. Then, create a second Widget that you put on the main window also. Then, right click on the "MainWindow" (in the Object Inspector) and go to the "Lay out" menu and select the "Lay out vertically". This will cause the two Widgets to take half of the main window each, i.e., one filling the upper half, the other filling the lower half. At this point, you can set fixed sizes or whatever else if you want to change how the two Widgets split the main window. Finally, you can add whatever else you want in either Widget, like a QPaint object or whatever else.

You can also create many other kinds of lay outs, and they are very useful for placing different objects in different places. It is also good for automatically adapting the sizes of things when the main window is resized and stuff.

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

Welcome to Daniweb!

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

I don't know what the exact numbers are, but one thing is for sure, if you were to compile a sum of all the down-votes versus up-votes found throughout the database, you'd get an overwhelmingly positive count at the end. That speaks to the fact that we, human beings, prefer positive reinforcement as the main mechanism for learning to live in a community. That's great, but it doesn't mean that there's no place for the opposite mechanism too, i.e., the occasional slap on the wrist. I think that down-voting does have its place, because at times it is useful in ways that can't be substituted by other mechanisms. If I want to convey messages like "I strongly disagree with that", or "this post is a nuisance or useless", without necessarily demanding a ban or infraction or deletion of the post or anything that harsh, and without creating a flame war with the poster, then the down voting works well.

And down-votes do convey a message. I, like many other veteran posters, have an overwhelming amount of up-votes, but also a number of down-votes. A few times, I've looked through my list of "down-voted posts", and what I see there is usually two things: people who down-voted because they didn't like to be told that they needed to show some effort/work towards solving their problem and that we wouldn't just give them homework solutions; and a number of posts that I have made in the past when I was in a …

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

The problem is that your Forward_Euler method takes function pointers as parameters, but "f", "gleft" and "gright" are member functions of the class C. These are not the same thing and thus, you get errors.

There are a number of options to solve the problem.

1) You could make the Forward_Euler function take member function pointers, but then it must be member functions of class C. What I mean is that you'd need this signature for the Forward_Euler method:

Eigen::MatrixXd B::Forward_Euler(C& c_obj, double (C::*f)(double), double (C::*gleft)(double), double (C::*gright)(double));

And then, within that function, you would call the functions as so:

double a = c_obj.*f(1.0);
double da = c_obj.*gleft(1.0);

This solution might not be practical if you want to use that function with function pointers that are not members of the class C.

2) In the OOP style, you could create a base class for a class that contains these three functions, as so:

class DifferentiableFunction {
  public:
    virtual double f(double) = 0;
    virtual double gleft(double) = 0;
    virtual double gright(double) = 0;
};

And then, your C class would inherit from that base class, and then you can make the Forward_Euler method with the following signature:

Eigen::MatrixXd B::Forward_Euler(DifferentiableFunction& f_obj);

And call the function as this:

    if(fdtype == 'f')
        u = b.Forward_Euler(*this); 
    ...

3) You could make the Forward_Euler method to take in std::function objects (which are generic function wrappers provided by the more recent compilers (C++11)). As …

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

Line 5 uses "non-static data member initializers". This is a new feature of C++ (C++11) and many compilers do not support that feature yet. I compiled your code successfully with GCC 4.7.3, and I would guess that version 4.7.0 and above will compile it fine. However, version 4.6.3 does not compile this code, saying that "non-static data member initializers" is no implemented yet. So, that's that.

Without support for C++11, you're gonna need to make a constructor to initialize your non-static data members, as so:

class IceCream{
private:
    int flavor[3], topping[3], scoops[3];
public:

    IceCream() {
      flavor[0] = 0; flavor[1] = 0; flavor[2] = 0;
      topping[0] = 1; topping[1] = 2; topping[2] = 3;
      scoops[0] = 4; scoops[1] = 5; scoops[2] = 6;
    };

    int getFlavor(int);
    int getTopping(int);
    int getScoops(int);
    void setFlavor(int);
    void setTopping(int);
    void setScoops(int);
} flavorX, toppingX, scoopsX;

I know it is annoying, but that's the way it is.

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

I realized that writing an essay is very important

Writing essays was fun. I particularly enjoyed taking the reader on for a wild ride, making sure my essays wouldn't be just another essay in the pile the prof had to grade (or the pile of cover letters for some job / scholarship application). It has worked wonders for me. I always had between 95 and 100 percent on all my essay regardless of my bad spelling / grammar or if I even read the book the essay was on. The real secret to a good essay is to think about the reader and making his/her experience the best possible when reading it.

Why did you pick this movie?

I don't know for sure, but knowing what the movie is about, there's a pretty good hint. The movie is about a bunch of blasé prep-school seniors who get inspired by this "passionate" teacher that teaches them about poetry and about some (hollywood-cliché) life-lessons, it's a classic passing-of-age movie. At the end, everyone is happy and changed for life, and tears flow on your cheeks as you watch the movie. Maybe LastMitch figures you're just the right age to be inspired by this movie, and I guess he could be right, but it's not like he would know anything about what you like, what you can understand or what "lessons" you need to learn about, just by knowing your age. And also, it's not like you need to …

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

Why are your listOfItems object vectors of vectors? From all your previous examples, it seems to me that it should just be vectors, as so:

std::vector<listA> listOfItems1;
std::vector<listB> listOfItems2;

And when you use that, it works fine. If you wanted to use vectors of vectors of object which also contain a data member that is a vector (or container of some sort), then you'll need to change the loops in the function (to have three nested loops, with only the most nested loop that uses the container referred to by the pointer to data member).

I'm also reading up on "pointer to data members"

Yeah, pointer to data members are not very popular / well-known. They are generally not that useful, but it's good to be aware of that possibility, because once in a while you stumble upon a problem like the one in this thread, and they can provide an elegant solution. Did you know that pointers to data members (as well as to member functions) can also serve as template arguments? Not that it's useful in this particular case, but it's a neat trick.

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

Yeah, the C++11 feature I used (the auto keyword) was just to save space and keep the example cleaner. It's not needed of course.

myk45 commented: agreed +0
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

<off topic>

BTW, what do those tags (<off topic>) do? Are they just indicators?

Not familiar with HTML or similar languages? Anyone (or any geek) familiar with HTML-like syntax will automatically recognize a structure like <foo> ... </foo> as meaning "start of a block of 'foo', containing ..., and then it ends". In this case, it means a block containing an off topic discussion (as, for example, LastMitch asking you some off-topic question / taunt in the middle of a forum). The system on Daniweb doesn't parse this block and never has, but it is a safe bet that the readers and their geeky minds will parse it correctly.

</off topic>

You should watch this movie called:

Dead Poets Society

I remember seeing that movie some years back, not bad, I thought it was touching but also very cliché. The performance of the actors were very good, but that's about all that is memorable about it, IMHO. And I'm not a big fan of movies that are just vessels for actor performances. I've been blessed with a few very inspiring teachers in my years in school, including an English literature teacher, so the cheap, dramatized, hollywood version of it wasn't very memorable to me.

I find that Scent of a Woman was a much better movie, and did a far better job at conveying its messages, and with impeccable acting too.

Reverend Jim commented: Hoo-ah! +0
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

First, you can use the standard function std::unique (from <algorithm> header) to remove any consecutive spaces by using this predicate (requires header <locale> for the std::isspace function):

bool isConsecutiveSpace(char a, char b) {
  if(std::isspace(a) && a == b)
    return true;
  return false;
};

// call std::unique as so:
std::string my_string = "     Big   Bob  ";
std::string::iterator it_end = std::unique(my_string.begin(), 
                                           my_string.end(),
                                           isConsecutiveSpace);

Then, it is just a matter of removing the first and last characters, if any are spaces too. As in:

std::string::iterator it_beg = my_string.begin();
if(std::isspace(*it_beg))
  ++it_beg;

if((it_end != it_beg) && std::isspace(*(it_end - 1)))
  --it_end;

std::string result(it_beg, it_end);  // copy into the result string.
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

If it is a method that any kind of "ExtraTerrestre" can implement in some way (as it seems from your code), then that method should be a virtual method of the base class (ExtraTerrestre) and overridden in each derived class (Dalek and Cylon). As so:

class ExtraTerrestre {
  public:
    // ... other stuff.

    virtual void putAlien() = 0;  // a 'pure' virtual function.
};

class Dalek : public ExtraTerrestre {
  public:
    // ... other stuff.

    void putAlien();
};

void Dalek::putAlien() {
  // implementation here.
};

class Cylon : public ExtraTerrestre {
  public:
    // ... other stuff.

    void putAlien();
};

void Cylon::putAlien() {
  // implementation here.
};

Then, you will be able to call the "putAlien" function on all ExtraTerrestre objects, and it will be dispatched to the correct implementation in the derived class.

If, on the other hand, it is not a function that any ExtraTerrestre can implement, then you should either create another base-class for that purpose (e.g., "PutableAlien" or something like that) that would contain the virtual method in question, or you can use a dynamic_cast operator to cast the object pointer to the class which has the method in question.

Oh.. I just realized that you might be talking about the "resetPositionAlien()" function that is called after constructing the objects. For that, you can simply do this:

       {
           Dalek* new_alien = new Dalek(7,200);
           new_alien->resetPositionAlien();
           alien[typeA] = new_alien;
       }
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Let me demonstrate why all your trivial examples and tests are flawed due to their simplicity. I created the following C example code:

int just_if(int value) {
  int result = 0;
  if(value == 1)
    result = 2;
  if(value == 2)
    result = 4;
  return result * result;
};

int else_if(int value) {
  int result = 0;
  if(value == 1)
    result = 2;
  else if(value == 2)
    result = 4;
  return result * result;
};

int main() {
  return just_if(1) + else_if(2);
};

which I then compiled to obtain the assembly listings for it. Here is how the "just_if" function looks like:

_Z7just_ifi:
.LFB0:
    cmpl    $1, %edi      // compare 'value' to 1
    movl    $4, %eax      // put value of 4 in 'result' (eax)
    je  .L2               // if comparison was true, jump to L2 (just returns)
    xorb    %al, %al      // set 'result' to zero (using bitwise-xor)
    movl    $16, %edx     // put value of 16 in edx
    cmpl    $2, %edi      // compare 'value' to 2
    cmove   %edx, %eax    // if comparison was true, set 'result' to edx (16)
.L2:
    rep
    ret                   // return

And here is the else_if function:

_Z7else_ifi:
.LFB1:
    cmpl    $1, %edi      // compare 'value' to 1
    je  .L9               // if comparison was true, jump to L9
    xorl    %eax, %eax    // set 'result' to zero (using bitwise-xor)
    movl    $16, %edx     // put value of 16 in edx
    cmpl    $2, %edi      // compare 'value' to 2
    cmove   %edx, %eax    // if comparison was true, set 'result' to …
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Cygwin is basically what you want. It is exactly that, a unix-like terminal for Windows. It isn't perfect (but nearly so), and might give you a bit of trouble here and there, mostly if you didn't install the packages (in the manual install configurations) that you needed (and, as a beginner, you might not know what you need, so it's a bit of a catch 22). Cygwin is like a Linux-in-a-box program with a very rich set of packages that you can install (using their "setup.exe" program), almost as rich as some basic Linux distributions. With those packages, you can basically get just about every unix tool (including "bash", and much more), or more precisely, the GNU toolset (GNU implementations of classic Unix tools and more, as in "GNU/Linux" which means GNU-toolset + Linux-kernel, well, cygwin just replaces the "Linux-kernel" with "Windows-wrapped-in-a-POSIX-API"). Remember, the Unix "style" is that the overall system is composed of thousands of small programs (tools) each with a very specific task.

Anyway, if you had an error saying that "bin/bash" didn't exist, try checking the list of installed packages and make sure all "bash" related packages are installed ("bash" is not one of the default/minimal-install packages). In general, a package-rich install of cygwin should be able to meet all your unix shell scripting needs and much more.

Another option is, of course, to get Linux either in a virtual box (VirtualBox or VMWare), or as a dual-boot (a bit more …

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

You could just use a pointer to a data member of the class held by the upper-level list. In other words, you can use this:

template <typename TopContainer, typename TopElement, typename BottomContainer>
void genericFoo(const TopContainer& topList, BottomContainer TopElement::* bottomList) {
  for (auto it = topList.begin(); it != topList.end(); ++it) {
    // ...
    const BottomContainer& list2 = (*it).*bottomList;
    for (auto it2 = list2.begin(); it2 != list2.end(); ++it2) {
       // do some stuff
    }
  }
};

Then, call it like this:

int main() {

  genericFoo(listOfItems1, &listOfItems1::value_type::listOfToys);
  genericFoo(listOfItems2, &listOfItems2::value_type::listOfApples);

  // or:
  genericFoo(listOfItems1, &Item1Type::listOfToys);
  genericFoo(listOfItems2, &Item2Type::listOfApples);

};

Enjoy!

myk45 commented: thanks! +5
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

But could this somehow lead to a crash? (say some illegal access of memory)

Sure it can. For example, what if, in the middle of a loop that iterates, with iterators, through the elements of a vector, another thread resizes the vector, effectively changing the memory location of the elements and invalidating any existing iterators. That's a simple example, but that basic logic carries over to many many more examples, some much less obvious than this one. Then, there are some more subtle problems that might not lead to a crash but might result in corrupt results, like non-atomic reads of variables or objects that might give corrupt values leading to corrupt results.

I needed some clarifications w.r.t making functions thread safe.

I prefer to think of it as making data accesses thread-safe. Any data that is shared between multiple threads (either as some shared "singleton" data, or inter-thread communications) should be protected in some way to avoid concurrent uses of that data in ways that could lead to trouble, as in my examples above. Usually, this implies making the access to the data possible only through some specific channels (e.g., member-functions), and then including some mutual exclusion mechanism within those functions.

It would help if you gave more details as to what you are really trying to accomplish.

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

Well, in that input() function, the object f2 is 0 (default-constructed). And then, by calling plus(f2);, you are actually adding f2 (which is 0) to this (the object on which the input() function was called), but within the plus() function, the result of the addition is stored within a local object (called second in that function) and then returned. However, in your call plus(f2);, you do not keep the resulting value of the function, and thus, in effect, the call is useless (has no effect except wasting computing time).

I'm not sure if you understand that C++ uses what is called "value-semantics" meaning that the parameters (fraction second) that you have on all those functions are copies of whatever object is passed to the function calls. In other words, calling plus(f2); does not modify the variable f2, it just makes a copy of it, passes it to the plus() function, and the plus() function just works on the copy, not the original variable. If you want that kind of semantics, you need to mark the parameters as references, i.e. with ampersand & character following the type, as in:

fraction plus(fraction& second)

With the above, any modification to second will also be applied to the variable passed at the function call (in technical terms, second becomes an "alias" for the passed variable, i.e., the variable is passed by reference).

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

This line is the problem:

fraction::fraction(1, 10);

If I understand correctly, you assumed that this line would construct sec with the given parameters (numerator, denominator). However, this is not how you call a constructor, in fact, I don't think the compiler should allow you to do that at all. The constructor is a special function which is called implicitely when you create an object. In this case, you need to declare the object sec with the parameters that construct it, as so:

fraction sec(1, 10);

So, that should work:

int main()
{ 

  fraction f;
  fraction sec(1, 10);

  f.input();

  cout << "1/10 + ";  

  f.output();

  cout << " = ";

  fraction result = f.plus(sec);

  result.output();

  cout << ". " << "which is also ";

  result.toDecimal(); 

  cout << endl;

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

i need base* b = /*derived*/d; done backwards

That is exactly what the static_cast does. Why do you assume that doing base* b = d; makes it so that b contains the same address value as d. In fact, there is no guarantee that it will. In a single inheritance scheme, it might be reasonable to expect that the address value isn't going to change across the cast, but there is no specification or requirement that it must be so. This is implementation-defined.

When it comes to standard behavior, cast operators are pretty interesting because there is very little guarantee, and overall, the idea is that you should never really be concerned about what the actual addresses are. You could summarize the guarantees about pointer casts as follows:

  • When casting up or down a class hierarchy (base and derived classes), as long as the casts aren't ambiguous, the guarantee is that the pointer-value (address) will be correctly updated (by an offset, possibly a zero-offset) to make it point to what you want it to point to (the sub- or super-object of the type given in the cast expression). In other words, the observable behavior is well-defined, but the implementation (actual changes in address values) is not.
  • When casting from a class-pointer type to some integer type (or void*), then the only guarantee is that you can cast it back to the same class-pointer type and get the same address back again.

Essentially, anything else that you might …

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

The easiest is probably to simply keep a variable, call it totalSales, to which you add the cost of each ticket that is bought, as they are bought. So, after line 25, you can add:

double totalSales = 0.0;

Then, right after line 104, you can add this line:

totalSales += seatPrices[row-1];

And finally, between line 125 and 126, you can add this line:

cout << "         Total of sales so far: " << totalSales << endl;

And that should do it.

The more complicated solution would be to loop through all the seats and check if they are Taken, and if so, add the cost of that ticket to the sum total.

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

Well, I looked at spoj, and they do have different versions available for most of the other languages too. For C++, they explicitly say (g++ 4.3.2) and (g++ 4.0.0-8) which are the GCC C++ compiler versions 4.3.2 and 4.0.0. These are both fairly ancient compilers. If you look at GCC version history, you'll see that 4.3.2 dates back to August 2008, and version 4.0.0 dates back to April 2005. I don't know why they would single out these two particular versions, but my guess is this. The 2005 version states, in the change logs, that only experimental support for TR1 is provided, which hints at the fact that this compiler is probably fully compliant to the C++98 standard but didn't yet include much of the ammendments / additions of C++03 standard (from 2003). The 2008 version probably has complete support for C++03 and TR1 libraries.

Now, why would there be a choice? Wouldn't everyone just want to use the latest version they provide? Well, if you want to make sure that your code is compilable even on an old compiler that supports on C++98 features, then you might want to use that older compiler. Very often, installing an ancient compiler on your own computer can be a real hassle, so an online utility might be a good little tool for checking small things.

You have to understand that programming languages are constantly evolving. Languages like C and C++ are extremely highly used throughout the world, and thus, they are governed …

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

Hi Glen, and welcome to Daniweb!

I am Canadian, and my last name is also Persson. What are the odds, eh? I'm from Quebec, i.e., french-canadian, so I'm used to getting that name messed up all the time, either mistaken for "Pearson" (common english-canadian last name) or for "personne" which means "nobody" in French (when I say: "Hi, my name is Mike Nobody." I get the weirdest faces).

I'm guessing you must have some Swedish ancestry? My father's Swedish, and I have lived there for a while myself.

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

Forum Linguistics 101:

What does OP stand for in OP Kudos:?

(a) Operating Peethan
(b) Obnoxious Pre-madonna
(c) Overflowing Pie-hole
(d) Original Poster

Which one of these multiple choices is correct?

LastMitch commented: Letter d. Thanks ! +0
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Usually, I find that the insertion / deletions are often easier to implement with a local "collect-destroy-rebuild" approach. What this means is that you inspect the local branches around the element to remove or near the place to insert. If you have the wiggle room necessary to simply remove/add the element, then that's all you do. If you need to do some restructuring, then you just figure out what is the root of the sub-tree that needs to be restructured (which is usually either the direct parent of the element to remove, or a close parent above that). Then, you do a little traversal of those nodes to "collect" them (collect the elements into a temporary storage). And then, rebuild a fresh sub-tree out of those elements. In my experience, this is not only easier to code, it is also cheaper to run on average than complicated tree surgeries.

Other than that, it is hard to give any kind of precise advice. You might want to provide a clearer explanation (and code) of how you store your nodes and how you link them.

And, do the index elements of a B+ tree necessarily have to be a subset of the values stored in the leaf pages?

As far as I know, no. However, it's probably rare to see an implementation that doesn't because it's trivial (both in coding and in run-time cost) to update the index elements whenever there is an insertion / removal of an element. And …

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

Use Qt. It meets all the requirements you mentioned. It is fast, easy, allows you to do simple menus and buttons, as well as drawings and pictures, and it works with both Visual Studio and GCC (both MinGW Windows and in Linux, or even Mac).

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

Where: in the source file (not in the header file).
How: like this:

// in my_class.h:

#include <list>

class MyClass {
  private:
    static std::list<int> privateList;
};


// in my_class.cpp:

#include "my_class.h"

std::list<int> MyClass::privateList = std::list<int>();

Or with whatever else you want to initialize it with.

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

Let me clarify your question for the less perspicace: You are using Visual Studio 2008, and you are looking to create COM objects (plug-ins) using the Active Template Library (ATL) for C++.

Have you tried going through the tutorials and manuals provided on MSDN?

Do you have any specific problem?

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

I think you've just agreed with me about the lack of morals in Hollywood.

I think you might have misunderstood me. You made the point that Hollywood lost its morality when they introduced more violence, cursing and sex in their main-stream movies. I refuted that by making the point that Hollywood never really had any morality to begin with, and the violence, cursing and sex doesn't change anything, it's just the latest "working recipe". Hollywood is in fact amoral, in other words, they never cared to produce films that convey any kind of good morals, they have always been only interested in selling products by sticking to recipes that work. So, on that level, we do agree that Hollywood productions lack morality.

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

Bullshit! I don't have to watch two or more people having sex together to know about the problems of sex. I don't have to listen to commedians using the F word whenever it suits him to know about ghetto problems. I don't have to watch one person cutting off another person's fingers to know about drug deals. Hollywood puts all these things in movies purely for profic, just for the $$$.

What you are describing are extremely insipid movies that are being juiced up with bits of sex, cursing and violence, for profit motives. That is exactly what I call Hollywood's wishy-washy attitude. It's easier for them to find a stupid boring script with no meaningful themes addressed in any meaningful or interesting way, and then juice it up. My point is, the problem is not so much the sex, cursing and violence, because these things are just the by-product of a complete lack of imagination, creativity, and critical thinking from the Hollywood crowd. And it is that which I am more afraid of, because it is a lot more dangerous to go on about your life with too few sources (of inspiration) that challenge you and develop your critical thinking, than it is to "be scarred for life" (sarcastic) by a few explicit scenes or some bad language.

Notice also that there are examples at the other end too. Take, for example, the Hollywood version of "The Girl with the Dragon Tattoo". They took a book that …

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

Hollywood lost all morals years ago when they started producing R rated movies which contain lots of violence, cursing and sex.

I beg to differ with granpa AD. How exactly can you address difficult moral topics without including things that are difficult to watch? Ignoring certain difficult realities is not "moral", it's delusional and denialist. The problem is not that there is violence, cursing and sex in the movies, because these things are sometimes necessary to make meaningful points about related topics / moral issues. For instance, in "Pan's Labyrinth", there are some pretty brutal and graphic scenes of violence, but it's there to make a point about the brutality of the Franco regime, and create a stark contrast with that little girl's fantasies. On the other end of the spectrum, you have movies like "Kill Bill" which is basically a cartoon and the "violence" is gratuitous but so far removed from reality that it doesn't have any real impact (one way or the other), it just makes for an entertaining movie and, that, I have no problem with either. The problem I find is all the wishy-washy stuff in between, and Hollywood loves to water-down anything that is too strong and juice up anything that is too plain, such that everything finds itself in the middle, with completely insipid "moral lessons", no contrasts, no interesting characters, etc. To me, this Hollywood attitude of "painting everything gray so as to not challenge anyone's thinking" is a lot more …

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

See this thread. It's a new feature that Dani is rolling out, there's been discussions about it on that thread I linked to.

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

From that last snippet, remove line 3. You don't need the head_ptr variable, since you never use it in the function (as the compiler is telling you), and the newNode variable is declared later (within the while loop). So, the function would become:

istream& operator>>(istream& infile, Bubble &mylist)
{    
   int num;
   int manynodes = 0;  // you need to initialize that variable.

   infile >> num;

   while(infile)
   {
      cout << num << " ";

      nodeType *newNode = new nodeType;
      newNode->info = num;

      newNode ->link = mylist.head_ptr;
      mylist.head_ptr = newNode;

      infile >> num;
      manynodes++;
   }

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

At line 49, you have this:

nodeType *head_ptr *newNode;

which is missing a comma, to give this:

nodeType *head_ptr, *newNode;

But, I guess you declare the "newNode" pointer again at line 59 (which is a better place to declare it), so line 49 should probably be:

nodeType *head_ptr;

That should fix your problem. If you have other problems, let us know.

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

But as Dani said, if there is someone you want to endorse, you can just go to his/her profile, go to the "Skills Endorsements" tab and clik on the big button to endorse that member. I think that's easy enough, and practical.

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

Ok, below is the basic logic, illustrated. I will mark the start pointer with "s", the end pointer with "e", the cursor pointer with "c" and the pointer to the end of the gap with "g". All characters marked as "X" are currently part of the gap (which is only logical, of course, as the actual values of the memory in the gap is just whatever was there before).

So, starting with an empty buffer of length 8:

XXXXXXXX
s       e
c       g

Notice how g == e and s == c at that point, so, the gap fills the entire buffer (capacity == 8, size == 0).

If the user enters the characters "Hi my", you get:

Hi myXXX
s       e
     c  g

Notice how the cursor pointer "c" always points to the place where a new character can be inserted. In other words, every inserted character is written to that place, and then the cursor pointer is incremented, effectively shrinking the gap.

Now, if the user realizes that there needs to be a comma between "Hi" and "my", he moves the cursor back to right after the word "Hi", in which case, a copy occurs which sends a few characters to the end of the buffer, and you get this:

HiXXX my
s       e
  c  g

Notice how the end-of-gap pointer has been moved back as valid characters were copied to the end of the buffer.

So, the user enters a comma:

L7Sqr commented: Very nice explanation and illustration +8
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

All I did is look-up the file "PdfContentsGraph.h" and ended up on this page. Then, I noticed the following line near the top of the header file:

#if defined(PODOFO_HAVE_BOOST)

And then, I wrote the post suggesting to add #define PODOFO_HAVE_BOOST. There's nothing magical about it. Are you saying that you spent "whole days and nights" trying to solve this problem about a class declared in the header file "PdfContentsGraph.h", and it never occurred to you to have a look at the code in that header file? That should have been the first place to look.

So, because PdfContentsGraph (this mini program) was built as part of the whole build process of PODOFO, the PODOFO_HAVE_BOOST macro is in the CmakeLists text file which is probably why it doesn't need it at the top of 'main' for the PdfContentsGraph program.

That makes sense. Another way is to just add PODOFO_HAVE_BOOST as a define in your own building options (in CodeBlocks or whatever else). Or, in command-line, you add -DPODOFO_HAVE_BOOST to the compilation command.

Why would I need to tell PODOFO that I have_boost when I don't do this for all the other dependencies for podofo such as zlib, libpng, libjpeg etc?

It's not unusual to have to do this kind of thing when there are optional dependencies (or dependencies that once were optional). Some libraries even do that for required dependencies too.

Is it because Boost is an external library and not a …

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

Are you trying to get answers to your own questions?

Not really. I think I posted 3-4 threads asking a question. So, that's a negligible amount.

What value do you get from helping people?

Many things. A warm fuzzy feeling inside. Discovering different perspectives, different issues and interesting little programming challenges. Learning to be a better "teacher".

Has DaniWeb helped you forward your career?

I improved my programming skills, and that counts for something.

Have DaniWeb community members evolved into quality online friends?

To some extent, yes. There are certainly plenty of members who I respect a lot and enjoy having exchanges with. Then there are a few Daniweb members with which I have conversed in PMs to some extent. And finally, a couple of people have become online friends (or acquaintances, rather) outside of Daniweb (through emails, LinkedIn, etc.).

Have you ever done business with people you met on DaniWeb?

Sort of. I'm a PhD student, so I don't really do commercial business, but rather academic research. If that qualifies as my "business", then yes, and I have done business with people I met on Daniweb. In one case, I cooperated with another PhD student (met through Daniweb) to improve my own library, allowing him to use it in his research, and we've had a few good back-and-forths that helped both of us in our respective research / library. In another case, I did an informal code review for …

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

Try telling PoDoFo that you have the boost libraries. Add this line to the very start of your code (before including the podofo headers):

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

Here is a very simple implementation of a gap buffer:
(Disclaimer: If this is for a school assignment, don't hand in the code below, because it intentionally uses things that would be immediately spotted as plagarism)

class GapBuffer {
  private:
    char* start_ptr;
    char* cursor_ptr;
    char* gap_end_ptr;
    char* end_ptr;
    std::size_t capacity;

    void updateCapacity() {
      if(cursor_ptr == gap_end_ptr) {
        capacity *= 2;  // double the capacity.
        char* tmp_ptr = new char[capacity];
        std::copy(start_ptr, cursor_ptr, tmp_ptr); // copy the before-gap part.
        std::copy(gap_end_ptr, end_ptr, tmp_ptr + capacity - (end_ptr - gap_end_ptr)); // copy the after-gap part.
        // update the pointers:
        cursor_ptr = tmp_ptr + (cursor_ptr - start_ptr);
        gap_end_ptr = tmp_ptr + capacity - (end_ptr - gap_end_ptr);
        end_ptr = tmp_ptr + capacity;
        // swap the memory:
        delete[] start_ptr;
        start_ptr = tmp_ptr;
      };
    };

  public:
    GapBuffer(std::size_t aInitialCapacity = 256) {
      capacity = aInitialCapacity;
      start_ptr = new char[capacity];
      cursor_ptr = start_ptr;
      end_ptr = start_ptr + capacity;
      gap_end_ptr = end_ptr;
    };

    ~GapBuffer() {
      delete[] start_ptr;
    };

    GapBuffer(const GapBuffer& rhs) {
      capacity = rhs.capacity;
      start_ptr = new char[capacity];
      std::copy(rhs.start_ptr, rhs.end_ptr, start_ptr);
      cursor_ptr = start_ptr + (rhs.cursor_ptr - rhs.start_ptr);
      end_ptr = start_ptr + capacity;
      gap_end_ptr = start_ptr + (rhs.gep_end_ptr - rhs.start_ptr);
    };

    friend
    void swap(GapBuffer& lhs, GapBuffer& rhs) {
      using std::swap;
      swap(lhs.capacity, rhs.capacity);
      swap(lhs.start_ptr, rhs.start_ptr);
      swap(lhs.cursor_ptr, rhs.cursor_ptr);
      swap(lhs.end_ptr, rhs.end_ptr);
      swap(lhs.gap_end_ptr, rhs.gap_end_ptr);
    };

    GapBuffer& operator=(GapBuffer rhs) {
      swap(*this, rhs);
      return *this;
    };

    // insert char function:
    void insert(char c) {
      (*cursor_ptr++) = c;
      updateCapacity();
    };

    // remove char function:
    void removeLastChar() {
      --cursor_ptr;  // you just need to move back …
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

You should probably start by making a Dynamic Array, which is what is implemented in the std::vector class. The idea is simple. Instead of increasing the size of the array at every insertion, you keep it always bigger than it needs to be, using a base-2 rule for the size. In other words, you start with a size of 2, and when there is a request to add a third element to the array, you increase the "capacity" to 4 (2x2). When more than 4 elements are needed, you increase the capacity to 8, and then to 16, and so on so forth. At the end, you are never using more than twice the memory that you actually need, and you only have to very rarely (logN) increase the capacity.

A gap buffer works the exact same way (the whole power-of-2 rule for increasing capacity), but instead of having all the valid data at the start, you have part of it at the beginning (up to where the cursor is currently located) and part of it at the end (from the cursor to the end of the text), leaving a gap in-between. The size of the gap is just a matter of (capacity - size) where the capacity is whatever power of 2 is greater than the size. And to keep track of the various positions that are relevant, you simply keep different pointers within your class, like a pointer to the start of the array, one to …