getline reads into a string from a stream; it's not designed to swap data between two streams. But you can do this:
std::string line;
std::getline(std::cin,line);
std::istringstream hello(line);
getline reads into a string from a stream; it's not designed to swap data between two streams. But you can do this:
std::string line;
std::getline(std::cin,line);
std::istringstream hello(line);
fgetc is a C function. The C++ way to do it is
char ch = std::cin.get()
I would strongly suggest that you avoid using extern variables (They are global variables). If you're not familiar with problems associated with them then have a quick look on google www.google.co.uk/search?hl=en&safe=off&q=why+are+global+variables+bad
As to your problem - if all you're after doing is cleaning up main() and dumping some extra code elsewhere, then a simple function would seem to do the trick. (Or am I misunderstanding/oversimplifying it?)
Initialisation.h
#ifndef INITIALISATION_H
#define INITIALISATION_H
class ConfigManager;
class ObjectManager;
void InitObjects( ConfigManager& configManager, ObjectManager& objectManager );
#endif
It would certainly seem the simplest solution which should be quick to implement. (It doesn't particularly change or simplify your code, but it will take that code out of main)
Adding the .h and .cpp files to your existing project depends on the IDE you're using. In most popular IDEs, all you need to do is add a source and a header file to your project, the rest should be handled automatically - You'll need to #include the .h file from your main cpp file though, just like you do with iostream/string/etc.
It's a little bit vague, but I think it depends exactly on what your code currently does and how much those objects have got in common (more importantly, how much your initialisation code has got in common)
Are you currently implementing this using a lot of repeated code? If so, then there will almost certainly be some way of trimming down the extra "fat". Do you have an example of the way your objects are currently created/initialised?
If you're looking at any common code which exists between different class types, then what you're looking for might be solvable using template function(s), or building a relationship using inheritance, or some other design pattern.
The >>
operator is whitespace delimited by default when used with any kind of stream; including cin, fstream and stringstream; so you can use that to your advantage to turn a stringstream into a simple tokeniser
e.g.
#include <string>
#include <sstream>
#include <iostream>
...
std::istringstream hello("the cat sat on \n\t the mat");
std::string fred;
while( hello >> fred )
{
std::cout << fred << std::endl;
}
This is also doable for any other type of delimiter, though you need to fiddle a little bit if using something else such as commas etc (std::getline also works with stringstreams).
it either puts out c or some random number. Also I can not use isdigit unfort.
char c = ch;
if(c>=48&&c<=57)
cout << 'c' << endl;
A character inside single-quotes denotes a character value, so all you're doing here is printing out 'c'. This value has absolutely nothing to do with your variable c
.
Also, the intent of your code might be a bit clearer if you used character representations in your comparison instead of those "magic" numbers. (It also makes your code a bit more robust for character sets other than ASCII) i.e.
if( c >= '0' && c <= '9' )
With vb.net I understand how to verify a space is being entered, but with C++ everytime I try to verify a space it looks at me like im stupid.
Does VB.NET have recursion? What you've got in your code below is an infinite loop which will most likely crash your program when it overruns the stack
bool isSpace (char ch)
{
char c = ch;
if (isSpace(c)) c='\n'
Calling a function from within itself (recursion) is legal, although unnecessary most of the time; and you can't just do it un-checked like that.
In this particular case, what you're actually trying to do doesn't need recursion anyway. All you should need to do is check whether your character is equal to a whitespace character, which is usually one of ' '
, '\t'
, '\r'
, '\n'
Here, you have declared a variable called ptr
void question1() { int i=0; int* ptr=nullptr;
Here you are declaring a completely different variable, which also happens to be called ptr
and hides the variable you'd previously declared by the same name.
while(boolean!=false) { cout << "Enter number: " << endl; int* ptr=new int[i+1];
Since this new ptr
variable is declared inside your loop, it is destroyed at the end of your loop, and the new int[]
memory which you'd allocated is being leaked, since there are no other references to it in your program.
I'd suggest renaming one of your 'ptr' variables, and being careful to ensure that the memory you're allocating is properly tracked, and also deleted when you no longer needed. (Note, memory allocated using new[] needs to be cleaned up with delete[] - don't omit the subscript []
operator)
Alternatively, a smarter way to do this (without new/delete) would be to avoid yucky stuff like pointers and new/delete, then to replace it with a vector (which is a resizable "C++ array")
#include <vector>
// ... etc.
vector<int> temp;
bool boolean=true;
while(boolean!=false)
{
cout << "Enter number: " << endl;
int n;
cin >> n;
if(n!=-1)
{
temp.push_back(n);
}
else
{
for(int j = temp.size() -1 ; j>=0; j--)
{
cout << temp[j] << " " ;
}
boolean = false;
}
}
I must not use finite function like that you write me,I need to write function step by step which works for alphabetic sorting in C++...
Ancient Dragon's other suggestion was to do a google search for Bubble Sort - try that and you will get plenty of good links which describe how the algorithm works
You're misunderstanding somewhat. It is not possible to simply resize a 'raw' array (Whether it is created by new or as an ordinary array object).
Once an array is created in memory, it can't be extended - The reason being that you have no control over the layout of objects in memory. Arrays must be contiguous (that means they must be stored as one "chunk"), and there's nothing stopping your O/S from sticking a different object after the end of your array - therefore 'resizing' an array actually involves creating a new one, copying its contents (to the new, bigger chunk) and then destroying the old one.
If you wish to use a resizable array, then your best option is a vector. vectors are resizable because they do all of the create/copy/destroy internally without you needing to manage it yourself. The interface to a vector is based on arrays (meaning you can use the []
syntax which you're used to) - there are also other useful features of vectors, such as it knowing its own size, and being usable with other parts of the C++ standard library.
#include <vector>
int main()
{
// create an 'array' with 3 items
std::vector<int> my_array(3);
my_array[0] = 1;
my_array[1] = 2;
my_array[2] = 3;
// resize it by adding a new one
my_array.push_back(4);
}
Short Answer: No.
Long Answer...
You only need to delete something if
- You created the object using new (or you used some other library or function which created it with new)
- You own the object (i.e. it is not owned by a smart pointer or another class from another library)
- There are no other pointers anywhere in your program which are referring to the object
In the example you've given; assuming you're talking about deleting your iterator 'p' - it's an object with automatic storage duration - you haven't created it with new, therefore it will be cleared up as soon as it drops out of scope.
In fact, calling delete on it would be invalid (undefined behaviour) and could cause your program to malfunction or crash.
If you think you're getting memory leaks, have a look at anywhere that you're calling new with 'raw' pointers, then investigate whether there's anything you can do to reduce your usage of them (e.g. replacing raw pointers with std::shared_ptr)
e.g. - the following needs a delete because there's a raw pointer:
MyClass* bob = new MyClass;
delete bob;
but this uses a smart pointer which does the cleanup for you:
#include <memory>
std::shared_ptr<MyClass> bob( new MyClass );
// or..
auto fred = std::make_shared( new MyClass );
Is adding "goto" always introducing more unwanted side-effects than regular control statement? Is control statement always improve readability?
If there were any rules like this where you could use the word "always", then problems would be simple :)
There are more than mere "goto" alone or "control statement" alone that contribute in code readability and maintainability. In some cases, "goto" produces even more readable code than "control statement" does.
You've missed my point though, which is that sometimes while updating existing code you can spend days rewriting something which didn't need to change, and in-turn require your QA/Tester to spend days re-testing functionality which shouldn't have changed, through a desire to write well-formed code, when all you needed was a quick, dirty, ugly hack which took 5 minutes to code/test and gets the job done.
Just to clarify - i'm playing devil's advocate a little bit. i.e. Readability, maintainability, and all the other sacred cows which exist for the good of us all usually go out of the window when there's a tight deadline and the real-world factors start to bite. And these are the times when ugly hacks aren't so bad. Otherwise, if you've got all the time/resource in the world then you can write the most elegant and well-designed solution you like :)
However, it still has its own place where it is necessary to use
goto
because alternative solutions (using control statement) fails.
'fails' is not really the right word IMO. For every conceivable programming problem you can think of, there is always more than one way to solve it; and code which uses goto is no exception since it can always be refactored to use alternative flow control (functions, if/else, loops, etc). The question is one of time/cost effectiveness.
Usually its something like this: You have some code which works just the way you want it to work, except there is one minor caveat which needs a tweak in order to handle a particular case. It may be that reworking the flow to handle this causes ripples throughout your code and your design, and has a potential negative effect on other behaviour. That doesn't mean the other flow control itself has "failed", it means that there's a design issue, and reworking it will need additional design, implementation and testing effort beyond the simple case that you want to handle in order to devise a good solution.
- If dropping a 'goto' in to the code is the quick-easy-solution, chances are that its the "best" solution on the basis that the risk of introducing unwanted side-effects, or coming up against other constraints outweighs the ugly/undesirable factor of using a dirty hack.
However, if the existing code never had 'goto' in there in the first place, chances are that the …
Mainly because of an observation by Edsger Dijkstra in 1968, where he argued "GOTO Statement Considered Harmful" (Google it and you'll find copies of the white paper)
In brief, the observation is that (In general), the number of 'goto' statements a programmer uses in their code is inversely proportional to the overall quality of that code (i.e. the code is generally less bug-ridden, easier to read, easier to maintain, etc).
the 'goto' statement, like many other features, is open to abuse; although in general (i.e. 99.99% of cases), there's simply no need for it, because the kind of 'jump' operations which programmers usually want to do can easily be encapsulated in a simple high-level flow control statement, such as if/else, for, while, switch, break, etc.
Plenty of "old" code still exists where programmers have used 'goto', and one of its problems when someone comes to maintain it, is that often a programmer will simply chuck in a harmless modification, but maybe will want to modify the flow a little too - one of the real problems with 'goto' is that changing the flow of a block which jumps around is actually very hard to do, unless you simply add in another 'goto'. the result is usually that code which started out relatively simple with only a couple of 'goto' jumps starts getting increasingly harder to follow, and turns into "spaghetti" code where nobody really knows what its doing, or why, or whether its behaviour is even correct …
if Node
is a template class, then the way to create an object is to specify the type you want inbetween < and >
Node<int> my_int_Node;
Node<double> my_double_Node;
Node<bool> my_bool_Node;
//etc.
In answer to the subject line - 'how does recursion work'.
Recursion causes a new function call to be pushed onto your call stack. You may visualise it procedurally as a function which calls a function which calls a function etc. For example, an un-rolled "factorial" function would look like:
int factorial1()
{
return 1;
}
int factorial2()
{
return 2 * factorial1();
}
int factorial3()
{
return 3 * factorial2();
}
int factorial4()
{
return 4 * factorial3();
}
int factorial5()
{
return 5 * factorial4();
}
int factorial6()
{
return 6 * factorial5();
}
#include <iostream>
int main()
{
std::cout << factorial6() << std::endl;
}
You can see that each of the "factorialX" do exactly the same thing with different numbers - essentially this is what an un-rolled recursive factorial function looks like; factorial6() calls factorial5(), which calls factorial4(), which in turn calls factorial3(), etc.
If you were able to examine the function call stack for the above program, it would look more-or-less exactly the same here in this recursive example
int factorial(int n)
{
if(n > 1)
{
return n * factorial(n-1);
}
return n;
}
#include <iostream>
int main()
{
std::cout << factorial(6) << std::endl;
}
factorial(6) calls factorial(5) which in turn calls factorial(4) which in turn calls factorial(3), etc.
In summary, when a function calls itself, what happens is no different to calling another completely different function; recursion is not a 'goto' within a function it is a …
Everything which you learn from a book written in the past 10 years will be equally relevant long after C++0x becomes the accepted standard.
Equally, however, there's nothing at all which stops you using a compiler which supports some C++0x features; its never a bad idea to learn using the latest-greatest (stable) compiler for the language, and if you accidentally become exposed to some C++0x features along the way then that's not a bad thing really either.
Once you reach a certain stage, some of the new libraries are certainly worth learning - I wouldn't be too surprised if tools like regex and shared_ptr eventually became core to every C++ programmer's repertoire over the next few years - it would certianly make sense in new beginner books to introduce those as part of a C++ programmer's basic arsenal since they are useful on a very general level, much in the same way that STL iterators/algorithms have gained acceptance since the 1998 standard.
Why are you even using char* instead of the standard string type anyway?
'eof' is a flag on a stream; it signals that a failed read attempt to read past the end of a stream has occurred, in other words, by the time your loop comes to find out that the stream has failed, a complete iteration of that loop has already tried working with the failed read - therefore its already too late.
the correct idiom could be termed as "read while data exists to be read". Assuming that 'fc.getInFile()' returns an std::istream&
(or ifstream&), your loop would look like
while ( fc.getInFile() >> tmp )
{
// TODO: handle 'tmp'
}
Also, 'eof' isnt the only reason that a stream could fail. the above idiom catches all stream errors.
The fact that you have so many errors suggests to me that you need to start afresh, and create your program one bit at a time slowly. Don't write 100 lines of code without trying to compile it, write a few lines at a time, or one small function at a time, then compile/test - make sure the output is what you expect, and carry on. doing this takes 5 seconds, and will save you alot longer of wading through compiler errors.
When you go back to rewrite your code, keep the following things in mind:
Firstly, the struct and class keywords both do exactly the same thing in C++, except that the default access specifier for a struct is public. If you know how to use a class, then you know how to use a struct aswell.
Secondly, I strongly suggest you replace your usage of char[] and char* with string. using a raw character array to move string data around your program in C++ is an obsolete technique which will just cause you all kinds of problems.
finally, the default floating point type in C and C++ is double - you should prefer this to float.
Why would you want to pre-allocate memory for a linked list? If you want to do that, you may aswell use a vector (or a deque).
I don't think experience in large projects really has anything to do with it - even very small 1-man-band projects have to go through the same motions; the difference is that mini-projects can probably be sketched on a scrap of paper, and the amount to think about and learn is usually far more managable :-)
Writing a draft specification requires some understanding of the technology which you're working with (Note the word 'draft'. Specifications don't need to be anywhere near complete or concise before you start working - they usually end up being continually changed right up until the end of a project);
You'll probably be defining some of your inputs and outputs in your specification, this can depend on what the API's and libraries you're working with are capable of.
For example, You start out thinking that you want to display something on the screen using Library X, but you don't know how Library X displays something on the screen, then you have little chance of being able to determine what inputs you need until you know how Library X works. Later you decide that the output you thought you wanted is no good anyway, but having found your inputs, and learned something new about how Library X works, you decide that there's a better way anyway, and change the specification to match.
Various ways to reach that point involve spending time trying sample programs (from your own prototypes and/or from trying to understand someone …
Please provide more detail; Does your program compile successfully?
If not, then please post the compiler errors/warnings;
If so, what happens when you run your program, and how does this differ to what you're expecting?
That list is probably about the best advice on book recommendations that you're going to find; the first book on the list, Accelerated C++, is widely recognised as being the one of the best C++ beginner books available, particularly if you're familiar with "the fundamentals" (i.e. loops/functions/etc) from another language
You might be interested in this link too: http://www.parashift.com/c++-faq-lite/how-to-learn-cpp.html
This thread is missing the most important step IMO.
Software development always starts out with the statement of a problem; that is to say that Programming IS problem solving. With this in mind, you cannot expect to design a solution without first defining, in detail, what exactly you're trying to solve.
Most people can usually visualise a small/medium problem, but anything complicated needs more thought; the thought process might go as follows:
Not all of those steps will necessarily occur; and if they do, they do not have to occur in any specific order (except for the step where you initially define the problem). The key point to note is that unless you understand at least part of the problem, you have little hope of being able to create a solution.
Just as an example, think about a web browser
The problem: Unable to browse the web
The requirements (Why i want to browse the web and how i want to browse it):
- Specify an URL containing an HTML document
- Connect to the URL …
A character surrounded by single quotes is a single character value; a pair of double quotes indicates that its enclosed data is a string literal, which is represented in memory as a contiguous sequence of characters (a.k.a an array of characters)
Strings and single characters are like apples and oranges - for historical reasons to do with the way the 'C' language works, raw string data involves an additional invisible 'nul' character, which represents end-of-sequence. The difference in memory between 'a'
and "a"
is that "a" is actually two characters.
On an unrelated note, I had a brief look at the tutorial you said you're learning from; Is that your only learning resource? There are an awful lot of mistakes/errors on the page - it doesn't look like a particularly good tutorial to me - be aware that the things its teaching you are likely to be bad in C++ (or in some cases they may be wrong altogether).
things like 'game', 'player', 'room', etc don't sound particularly abstract to me :-)
Usually when I think about concepts, the initial question is "what does the program do - i.e. rather than considering the program as a bunch of uninteresting static objects, think about the interactions between them, especially in relation to the inputs/outputs of the program; this usually leads to being able to describe the parts of the program which will be more difficult to model - bits relating to its dynamic behaviour.
Assuming that a text-based game is going to be primarily text descriptions of objects, i'd guess that the most fundamental abstract concept which exists is that the all entities in your game world must be describable with a textual description; and there Describable could be your first 'concept'
After that, you may decide that some things in your game are also Attackable.. others are Usable. some things may be Destroyable (perhaps all destroyable items are also attackable, but not all attackable items are destroyable?).
Some entities may also have a particular 'state' which can change (like a door could be open/closed, a monster may be dead/alive, a destroyable entity may change from being "existing" to "nonexisting" after its destroyed..) - if its possible for an entity to have its state changed, then that might subscribe to a 'changable' concept.
When thinking about these concepts, they might end up in a loose heirarchy; otherwise they could simply serve as the "base" for …
I hate to be a bore, but Narue has written an extremely concise, in-depth post which is pinned at the top of this forum called How do I flush the input stream? - Please pay attention to sticky threads in future :-)
the ::
symbol is known as the Scope Resolution operator because it is used to specify the scope in which an identifier resides within your program;
The concept of 'scope' generally applies anywhere that curly brackets can be found { }
- the reason for the concept of scope is to allow the same identifier to exist within different logical partitions of your code. A namespace is one such type of partition, a class/struct is another. for example:
int num;
namespace foo
{
int num;
struct bar
{
static int num;
};
int bar::num;
};
int main()
{
::num = 1;
foo::num = 2;
foo::bar::num = 3;
}
if you read right-to-left, you could translate 'scope resolution' to 'exists within'. names which are not qualified with the scope resolution operator are assumed to be already declared within the current scope
Note that you may also have a block which exists in an unnamed scope, e.g. inside a function
int num;
void func()
{
int num;
{
int num;
{
int num;
}
}
}
For obvious reasons, it is impossible for the scope resolution operator to qualify names within an unnamed scope; if the scope resolution operator is used without a name, it is assumed to be referring to the global scope. Hence why some coding standards documents insist that global variables must be fully-qualified using the ::
symbol, to make them visually stand out against local variables.
What exactly do you mean by rules? There are no rules for Coding style - such coding standards are usually based upon one or more of:
If you really want a 'rule' to follow, then there's only one worth listening to, which is Be Consistent. i.e. don't write code in a whole mixed bag of styles - the most readable code is usually that which follows the same 'theme' throughout. If you can do this, then few people will complain, provided your code is well-formed.
You also might like to read this bit of advice from Bjarne Stroustrup
http://www2.research.att.com/~bs/bs_faq2.html#coding-standard
Yes. What else are you thinking someone would use it for?
Well, wiki's often contain all kinds of reference pages - it might have filled up with hyperlinks, off-the-shelf "FAQ" answers, full-blown tutorials, platform-specific code (although this might deserve its own separate section)
Not that I believe those things should be necessarily prohibited from the wiki, but its good to define its scope/intention IMO :-)
Excuse me if I may play devil's advocate a little.. I think the wiki is an excellent idea in principle, however my personal experience of wiki projects which go largely unmanaged is that they tend to fall apart and rapidly decay into a worthless disorganised mess if certain guidelines and principles aren't established before inviting external contributors to drop their load - I'd much rather see a successful wiki than one which nobody uses :-)
I didn't compile your program bench, but in some compiler you may need to use the
keyword, typename in your to_string function, specifically heretypedef std::iterator_traits<FwdIt>::value_type value_type
Well spotted - VS2008 didn't pick up on that even after I switched off MS-specific extensions, however if I use the same typedef in a class/struct, then it correctly throws out an error. I guess I should rely on the comeau compiler more often!
I believe you may be somewhat re-inventing the wheel here - you can achieve the same result using a std::stringstream, an ostream_iterator and the std::copy algorithm :-)
#include <string>
#include <algorithm>
#include <iterator>
#include <sstream>
template<typename FwdIt>
std::string to_string(FwdIt begin, FwdIt end)
{
//retrieve the value type for any kind of iterator, including a "raw" pointer
typedef std::iterator_traits<FwdIt>::value_type value_type;
std::ostringstream buffer;
std::ostream_iterator<value_type> buffer_inserter(buffer, " ");
std::copy(begin, end, buffer_inserter);
return buffer.str();
}
main/test:
#include <iostream>
#include <vector>
template<typename T, int N>
T* end_of(T (&arr)[N])
{ return arr+N; }
int main()
{
double foo[] = { 10.1, 20.2, 30.3, 40.4, 50.5 };
std::vector<double> bar(foo, end_of(foo));
std::cout << to_string(bar.begin(), bar.end());
}
I find the argument about simplicity to be somewhat perplexing - C++ and Java have amazingly simple syntax rules when compared to any natural language.
I reckon you could summarise the fundamental syntax of most programming languages using a handful of sheets of paper; on the other hand, natural languages are enormously complicated - linguistics experts fill entire books documenting the structure of languages such as English - the number of varying factors of words in a natural language is vast.
e.g. consider the changing meaning of these words simply by fiddling with punctuation
"Clive bent over because the book had fallen on the floor to the left of the shelf..."
"Clive, bent over because the book had fallen; on the floor, to the left of the shelf..."
"Clive, bent over, because the book had fallen on the floor, to the left of the shelf..."
"Clive bent over; because the book had fallen on the floor, to the left of the shelf..."
All of those sentences are 'technically' gramatically sound (either on their own or as part of another sentence), but please do try explaining the difference to a non-english speaking human letalone a computer :-)
Perhaps what you mean is that you are more familiar with English than you are with Java or C++, and you also probably aren't too familiar with how computers "think" either - but thats because you probably spent your entire life learning and English, …
what exactly is REGISTER_BUILDER? are you 100% sure that its a function? usually ALL_UPPERCASE names are reserved exclusively for #define macros
it would help a great deal if you could show us the definition of REGISTER_BUILDER.
"Most people" - presumably you're referring to the number of positive reviews on Amazon; Remember that the reviews are almost certainly all by people who are still in the early stages of learning, and aren't in a position to really be able to tell the difference between a genuinely good modern C++ book, and one which is simply out of date.
Depending on what your criteria is for a 'good book', they may be correct; but if you value your time, then alot of what you learn about programming from C++ primer plus will later have to be un-learned when you eventually graduate to using C++ properly - alternatively, you can start out learning it properly from day one, and have a much easier experience.
Are you asking for reviews? I don't own the book, but I am aware of its existance, and its outdated approach to teaching the language.
C++ primer plus is an old book which was "updated" after C++ was revamped and standardised; unfortunately, when C++ was reborn as a new language, this book was barely modified with a bunch of additional chapters tacked on to the end.
Back in its day, i'm sure this was a great book to learn C++ from, but these days its not worth wasting time or money with - thats not to say that the material is completely irrelevent, simply that other books have appeared in the past decade which are much, much better.
Have a look at the following reviews; all of these books are considered modern, and are written by people who understand the language, and the right way to teach it to beginners.
- "Accelerated C++": http://accu.org/index.php?module=bookrevie...ch&rid=1185
- "You Can Do It!": http://accu.org/index.php?module=bookrevie...rch&rid=470
- "C++ Primer 4th Ed": http://accu.org/index.php?module=bookrevie...rch&rid=778
- "Programming: Principles and Practice using C++": http://cplusplus-soup.com/2009/02/01/programming-principles-and-practice-using-c/
Tell your school that you are unhappy about being taught using obsolete technology. Turbo C++ has no place in today's world, and insist that they provide you with an education which is relevent - i.e. by teaching you using modern material which works on modern compilers.
You can use getline to read from a stringstream buffer upto a delimiter, then push each word into a vector (a C++ array)
#include <string>
#include <vector>
#include <sstream>
int main()
{
std::string line = "word1:word2:word3:word4";
std::istringstream buffer(line);
std::vector<std::string> words;
std::string word;
while( std::getline(buffer, word, ':') )
words.push_back(word);
}
That's a good one. Why not provide a sample?
typedef int roses;
typedef int violets;
typedef int sugar;
const int red = 1;
const int blue = 2;
const int sweet = 3;
const int you = 4;
int are(int) { return 0; }
int is(int) { return 0; }
bool so(int) { return 0; }
int main()
{
roses(are(red));
violets(are(blue));
sugar(is(sweet)) && so(are(you));
}
But if you're going to play Romeo, you should make one up yourself :P
Construction order has nothing to do with the compiler
Sorry, that's poorly worded; what I meant was "object construction doesn't happen at compile time".
Narue has a good linked list tutorial on her website here http://www.eternallyconfuzzled.com/tuts/datastructures/jsw_tut_linklist.aspx
If you're trying to wrap your head around the concept of linked lists, start out with something simple first - a singly-linked list which represents a stack is by far the easiest to write (because its simpler to build a list 'in reverse' than it is to build one forwards). Once you're comfortable with a singly-linked list, you can modify it to link in both directions (Doubly linked lists leave you with alot more to think about with regards to 'dangling' pointers)
Well the main problem with starting the construction of a class from the derived part up to the base is that any variables you are using that are in your base in a function in your derived class would be undefined. Assume this situation.
class A { int number; }; class B : public A { void foo() { number++; } };
In this situation the compiler would have no idea what number is when it tried to compile it if it were to start at B and go to A. Since it goes the other way there is no problem.
Construction order has nothing to do with the compiler - object initialisation happens at run time. Also, your code still has problems in that number is undefined by the base class irrespective of the order that the classes are constructed.
And lastly, foo is not a constructor, nor is it called by any constructors so is not involved in the construction order anyway.
A better example to illustrate construction order might be this
class A
{
int number;
public:
A(int n) : number(n) {}
void display()
{
std::cout << number;
}
};
class B : public A
{
public:
B(int n) : A(n)
{
display();
}
};
If the rule were that B must be fully constructed before creation of A can commence, then the constructor for B would have had to finish before A(n) is called - however, display() relies on A::number being well defined.
…
I don't really see how knowing "why" actually helps, although if you think about what inheritance represents, it should be obvious - a base class represents generalised components which are common to all objects in a heirarchy - essentially a base class is a 'sub set' of its derived classes - it makes sense that the common subset is created first before the specialisations.
Well I don't usually listen to music while programming (if i'm at work, I'm usually keeping an ear out for things happening around me), but here's my take on it :D
Visual Basic - Lady Ga-ga. Naff, Cheesy, Only appeals to teenagers. You probably wish you'd never heard of it in the first place.
C++ - Nine Inch Nails. Has stood the test of time - deep, quirky and always a little bit experiemental. You either love it or hate it.
C - Depeche mode. Eloquent, Brilliant, Definitely an acquired taste.
Java - Nirvana. Still annoyingly popular, even though most of us got bored with it a long time ago.
C# - Muse. Melodic, Adventurous, Thoughtful - Even if its not quite your cup of tea, you can't help but appreciate it.
F# - Rage against the machine. The very idea of it should have been dead a long time ago - but against all the odds it seems to be alive and kicking on a brand new wave of optimism. Will it last this go around? Time will tell.
Write her a poem using your favourite programming language! :D
Oh this is sombre news indeed. I would like to add my name to the end of the long list of people who really appreciated Dave's bold presence on Daniweb; in all the time I've spent lurking around these forums, his many contributions here never ceased to feel enlightening ro me; and the world is just that little bit emptier now.
My hat off to you Dave, you will be most sorely missed!
Ben
The problem with Amazon (Not just for C++ but for all programming languages) is that the reviewers of beginner books are usually buyers who haven't been learning their subject for very long (of course, why else would they buy a beginner book!).
In all likelihood, they don't really know (or care) about the difference between a book which teaches C++, and a book which teaches C in disguise. (Other titles which suffer the same false acclaim from "satisfied" buyers include 'C++ for dummies', 'C++ in 21 days/hours', and Herbert Schildt books).
The thing those outdated books' authors seem to have have in common is that they probably learned C++ 20-30 years ago when it was called 'C with classes', or they're simply programmers who've been signed up by publishers who don't care about creating good quality educational books (This seems to be partly the case with SAMS and IDG).
C++ was reinvented in 1998 when it was standardised; it turned from being a pure "superset of C" into (almost) a completely new language. So one possible indicator of the relevence of a book is to see whether its original 1st edition came before 2000-ish (in which case its most likely a 'C with classes' book which has been tweaked and reprinted), or whether its a book which acknowledges that C++ is no longer just a superset of C.
3 of the books I mentioned were written in the past 10 years, the other book is much …
Ah Thanks for the reply, I think I may get the C++ Primer Plus 5th edition, as it has like 68 5-star reviews and a one or two of the 1-2star review.
Don't trust amazon reviews!
C++ Primer Plus is totally different to C++ Primer, unfortunately C++ Primer Plus is another of book which doesn't really teach C++ in the 'right way' - it takes a very poor "bottom up" approach, and essentially teaches you a bunch of outdated 'C' style programming techniques, yet barely mentions the STL until the final couple of chapters 'tacked on' to the end of the book, which is pretty poor considering the STL is absolutely an crucual foundation of the C++ language. If you value your time, and would like to learn C++ the right way, i would recommend avoiding this one; otherwise, you may aswell learn the C language instead :)