Bench 212 Posting Pro

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;
    }
}
Bench 212 Posting Pro

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 );
Bench 212 Posting Pro

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 :)

Bench 212 Posting Pro

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 …

Bench 212 Posting Pro

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 …

Bench 212 Posting Pro

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.

Bench 212 Posting Pro

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?

Bench 212 Posting Pro

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:

  • Define the problem
  • Define the requirements of a solution (i.e. What tasks/activities do you want to be able to perform?)
  • Evaluate each of the requirements
  • begin to define the specifics (i.e think about what the solution should actually do)
  • Create one or more prototypes as necessary for various bits of functionality - this in itself will often unearth sub-problems which you hadn't previously considered

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 …

Bench 212 Posting Pro

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 …

Bench 212 Posting Pro

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.

jonsca commented: Nice explanations +4
Bench 212 Posting Pro

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:

  • Personal Preference
  • Conventional wisdom (i.e. what do 'most other people' do?)
  • Consistency with existing code (If you're modifying someone else's code)
  • Style imposed by your employer/project leader (these are the only "rules" which exist)

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

Ancient Dragon commented: Agreed +28
Bench 212 Posting Pro

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());
}
StuXYZ commented: good example +3
Bench 212 Posting Pro

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, …

jonsca commented: Nice arguments +4
Bench 212 Posting Pro

There are several beginner level books which often come highly recommended by the real experts/guru's in the C++ community; i.e. those people who understand the language, and also understand the correct way to teach it.

- "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/


The first book in that list, Accelerated C++, is an excellent introduction, but its extremely concise and condensed - the amount of good information per-page means that you might expect the same amount of information from a book with 3 times as many pages (although its worth reading cover-to-cover at least twice). if you're looking for a "gentler" introduction, then you might prefer one of the other books

"you can do it" is very hobbyist-friendly, and comes with a small graphics library which most of the book's examples make use of - again, this is a small-ish book, and covers the essentials of C++ with an emphasis on helping beginners get a firm grip on the fundamental building blocks - you would probably want to "graduate" from this one to Accelerated C++ if you were really serious about learning the language.

The other two books are more like big tomes. Principles and Practice is written by Bjarne Stroustrup - the man who created the C++ language; he uses that book to run Computer Science …

Bench 212 Posting Pro

I am curious, but wouldn't this allow *any* class that happens to allocate the same amount of memory as Small?

No, That's not how it works - there are two overloaded functions which are used to determine the convertability.

small test(base&);
big test(...);

the class checks the sizeof the return types of these functions. the sizeof the return type will only be 'small' when the class is convertable to base&, otherwise, the type will fall into the ellipsis.


This isn't in any way circumventing the language constructs - its completely portable, and works on well-defined behaviour of the ellipsis operator ...

Bench 212 Posting Pro
int length(string word)
{
	int len=0;
	for(int i=0; word[i]!=NULL; i++)
		len++;
	return len;
}

This function is completely unnecessary - it could also lead to undefined behaviour since the underlying representation of std::string is not necessarily "null terminated", which means that you could quite easily crash your program or do other strange things with this construct word[i]!=NULL However, it shouldn't matter, since std::string already has a "length" function;

std::string s("Hello, World!");
std::cout << "s is " << s.length() << " characters long" << std::endl;

Even if your length function appears to work, since a std::string is not null terminated, your length function may overrun if the first byte after the end of your string happens to be some other junk value (It may or may not be memory owned by the string - but don't leave it to chance - you've got a 50/50 chance of something going wrong). The only way to guarantee access to a null terminated string is with the .c_str() function - at which point you may aswell simply use strlen instead.

Bench 212 Posting Pro

Some would argue that get and set methods themselves are a symptom of bad design, but even in those situations, they are still superior than providing direct access to a private member variable because they at least do you the service of preventing someone from obtaining a pointer-to your class' local data - something which is nearly always a bad thing.

As others mention, there's also the scenario where a simple set/get combination cease to be simple if perhaps constraints are added to the data (maybe an exception needs to be thrown if the data is invalid?), or perhaps the storage of that data is exported off to some other part of the program and it ceases to be a data member.

The reason we employ design idioms often isn't to add flexibility to a program - quite the opposite, its to add strict constraints to stop other programmers from breaking our code, by forcing the compiler to kick up an error when some other bit of code does something dumb.

IMO, The worst kind of code is usually that which has been designed with the sole intention of saving keystrokes.

Sulley's Boo commented: riiiiiiiiiiiiight +6
Bench 212 Posting Pro
//main.cpp
#include <iostream>
#include "player.cpp"

int main(){
    players();
    return 0;
}

Note that i've included player.cpp, not player.h (Which i accidentally named header.h, soz)

This is a terrible way of doing things, and can easily end up in creating a mess - please don't encourage others to #include a source (cpp) file.

the correct code should look like this:

#include <iostream>
#include "player.h"

.cpp files are intended to be used to hold definitions - they're not to be included within other source files unless you want a mess on your hands (Except in the rare situation when you might be playing around with splitting templates between files, but that's not the case here). .

So, unless you have some compelling reason to do otherwise (such as with templates) you should only use #include on a header file.

pspwxp fan commented: tnks :) +1
Bench 212 Posting Pro

the : after a constructor signature denotes the start of an initialisation list. Have a look here for a more detailed explanation:
http://www.cprogramming.com/tutorial/initialization-lists-c++.html


Line 18 is a template for an overloaded constructor which takes an array by-reference (Not by-pointer); Its not an essential part of the class though.

template<int N>
double_linked( T (&arr) [N]) : head( NULL ), tail ( NULL )

I added that to the example as a way to quickly initialise double_linked using an array of size N (where N is the template parameter, automatically deduced by the compiler).

An instance of that constructor is used here:

int arr[] = { 4, 6, 8, 32, 19 } ;
double_linked<int> dlist ( arr );

this call will create a constructor with the signature double_linked<int>::double_linked<5>(int (&)[5]) by way of deduction - the compiler knows that the array is size 5, and fills in the blank 'N'

Bench 212 Posting Pro

Here I know what exactly happened, and I want to show this message to the user

This is your major problem - exceptions should not be used for handling user errors, and users shouldn't need to know about exceptions which have occurred in your program - That is to say, if the user does need to know about it, then its not really an exception.

If you know exactly what happened, then you can deal with it in some other way. Exceptions are generally used for handling mistakes which you or another programmer might make when using your code - where those mistakes affect the inner workings of something else; for example, passing invalid data to a constructor or running an iterator or loop beyond the boundaries of a container. - situations where the best solution to a problem is to throw the error back to the calling code, and let that code clean up any mess which may have been left over.

You may be approaching C++ exceptions with a Java mindset, where exceptions are often used to handle all kinds of things (obviously, C++ is not Java). In C++ you should only use exceptions to handle circumstances which are truly exceptional - user interaction really isn't one of those things, since you should always be expecting that a user is likely type in something wrong, and don't really need to throw errors back to calling code.

Most of the time validation which can decay into …

Bench 212 Posting Pro

Probably the easiest way is to use a map (An associative container), which lets you associate "keys" (identifiers) with values/objects.

hello world;
    world.name = "Earth";
    world.size = 100;

    hello people;
    people.name = "Everyone";
    people.size = 2;

    std::map<std::string, hello> table;
    table["world"] = world;
    table["people"] = people;

STL maps come with a premade 'find' function, to let you find whether or not a 'key' exists within that map

std::map<std::string, hello>::iterator iter;
    iter = table.find(classname);

if the iterator returned by find reaches the end of the table, then that object doesn't exist in the map (strings are case sensitive too), otherwise you can use the iterator to access the object

if( table.end() == iter )
        std::cout << "object \"" << classname << "\" not found";
    else
    {
        hello& object = iter->second;
        std::cout << object.name << ' '
                  << object.size << std::endl;
    }

(quick example)

#include <string>
#include <iostream>
#include <map>

struct hello
{
   std::string name;
   int size;
};

void display_hello(const std::string& classname, std::map<std::string, hello>& table)
{
    std::map<std::string, hello>::iterator iter;
    iter = table.find(classname);

    if( table.end() == iter )
        std::cout << "object \"" << classname << "\" not found";
    else
    {
        hello& object = iter->second;
        std::cout << object.name << ' '
                  << object.size << std::endl;
    }
}

int main()
{
    hello world;
    world.name = "Earth";
    world.size = 100;

    hello people;
    people.name = "Everyone";
    people.size = 2;

    std::map<std::string, hello> table;
    table["world"] = world;
    table["people"] = people;

    display_hello("world", table);
    display_hello("people", table);
    display_hello("blah", table);
}

It would probably be better to wrap the map …

jonsca commented: Nice post +1
Bench 212 Posting Pro

Modern C++ beginner books start out by introducing vectors early on, sometimes without mentioning arrays at all except for the final chapters where they're discussed in among the 'C' subset of the language.

They do this for a good reason; C++ has been deliberately designed with the aim that programmers should never need to use arrays; the STL which all but replaces arrays is easy to learn, easy to use, safer, and usually more efficient. (Despite this, there are still a few odd situations where arrays are the best solution to a problem, but those are less common.).

If you're still in the early learning phase, skip arrays for now and focus on the STL (Hopefully you have a modern book which does this too). You lose nothing by learning how to use vectors, iterators and algorithms, and hopefully gain alot more in the time you spend than if you were to spend alot of time working with arrays.
You can go back to arrays later on when you're more comfortable with the basic parts of the STL, and you'll be in a far better position to see for yourself why arrays don't get used much.

Bench 212 Posting Pro

Sequences of characters (i.e. 'words' or 'plain text') are known as strings. In C++, strings are represented as a type of data called string

#include <string>  //allows you to use 'string'
#include <iostream>

int main()
{
    using namespace std;

    string name;
    cout << "What is your name?" << endl;
    getline(cin, name);
    cout << "Hello, " << name << endl;
}

Output

What is your name?
Joe Bloggs
Hello, Joe Bloggs

You can use >> aswell if you really want to, but be careful that >> only reads up to the first 'whitespace' character and leaves the rest of your input alone to potentially trip you up later on. (Which means that if you're on a modern desktop system, the next time you try to do something with 'cin' the first input you'll encounter will be whatever was left over)

#include <string>  //allows you to use 'string'
#include <iostream>

int main()
{
    using namespace std;

    string name;
    cout << "What is your name?" << endl;
    cin >> name;
    cout << "Hello, " << name << endl;
}

Output

What is your name?
Joe Bloggs
Hello, Joe
Bench 212 Posting Pro

hey, everyone. I am still learning templtes and I have 2 questions:
1-Why is it that all the examples of templates I have seen are about arrays?Is that all templates are used for?

I suppose because containers are the most prominent and easy-to-explain examples when it comes to introducing templates - its probably safe to say that you'll encounter a vector very early on in your C++ learning, and a vector is a great example of an application of templates.
Beyond that, templates can be (*ab)used for some immensely complicated, mind-bending solutions to address some very large and difficult problems.

* = Some would argue that templates were intended to be simple, but the true C++ Guru's in the world discovered that templates were actually capable of almost standing alone as an entirely new turing-complete programming language, albeit one which is incredibly ugly and sometimes hard to understand, but extremely powerful nonetheless.

2-after pondering about the above question, I decided to try something else witha template..a generic unction.
However the program just hangs when I run it. Only one object is created(because I always put a sentence in my constructors, to know when an object is created. the sentence appears only once.)
Can someone help me out? Thanks in advance!!

T dat1,dat2;
 display():dat1(0),dat2(0){

Your initialiser list assumes that dat1 and dat2 are capable of taking 0 as their constructor argument - but for std::string, this will actually do something really dangerous (that zero converts …

Bench 212 Posting Pro

A few comments

- When handling dynamically allocated memory in C++, you should use the new operator. Malloc is bad, since all it does is allocate memory on the heap - if you're creating an object of a particular class/struct, then that object will be uninitialised.

- Keep in mind the rule of three, which states that if your class needs either a Copy Constructor, a Destructor, or an overloaded assignment operator, then it generally needs all 3.


In reply to Alex Edwards - What exactly do you intend the copy constructor in your example to do? at the moment the program displays undefined behaviour where you have a dangling pointer to an array which will be deallocated as soon as the object has been created. The result is neither a deep nor shallow copy of the original object, but just an object in an invalid state.


To the OP - perhaps you could explain exactly what it is you're trying to do here since void pointers are generally unsafe (You need to know exactly what you're doing in order for them to be meaningful); The initial example you provided is displaying that output because your object is being directly copied value-for-value (A shallow copy). Which means your array is copied as you'd expect, and the pointer member is also having its value copied.
If you posted the copy constructor which you tried, someone may be able to point out where …

Alex Edwards commented: Thanks for pointing that out! +3
Sulley's Boo commented: and happy belaaaaa..aated b-day :D +5
Bench 212 Posting Pro

at this line pizza.set ( x , y , a[7] , i ) ;

a[7] is an element in your array
(Also - if your array is only 7 elements in size, then valid elements are indexed 0-6, so you're accessing one-past-the-end.)

try this instead pizza.set ( x , y , a, i ) ;

Duki commented: thanks for the help +4
Dave Sinkula commented: Thanks. I had made that change but forgot to post it. +11
Bench 212 Posting Pro

That's the one that made me wonder if it was practical. All of the examples that look useful to me are too complicated to understand. All of the examples I can grok are kind of pointless. In the factorial one, you have to give the template a literal. If you know the literal you want, why not just use the factorial answer as a literal instead of some convoluted scheme of finding it at compile time with templates?

I just don't get it. :(

I understand your frustration.. there's still one or two pages in the book Modern C++ Design that frankly leave my head aching when I try to work out what the examples are actually doing

Yes, the factorial program on its own is rather pointless - it just shows how loops can be unrolled at compile time. Then again, most examples that you find in books are usually contrived, useless programs. I'm sure this can't be the first time you've looked at something in C++ and thought to yourself "Why on earth would I ever want to do this" :)


I think the advantage of template metaprogramming is two-fold. First, there's the minor goal of making your program more efficient, by performing certain routines at compile time. Although, if it were just about fine-tuned optimisation, then I expect most people wouldn't bother.

The more important goal (IMHO) is that doing these processes at compile time means more errors are picked up at …

Bench 212 Posting Pro

I appreciate your useful help and links, but I don't think I'm smart enough to understand template metaprogramming. Even the simple rebind you showed me before doesn't make any sense...

its a rather elaborate complicated example of template metaprogramming for a newbie IMHO. Try this as a simpler one :)

template<int N>
struct factorial
{
    enum { value = N * factorial<N-1>::value };
};

template<>
struct factorial<1>
{
    enum { value = 1 };
};

#include <iostream>
int main ()
{
    std::cout << factorial<6>::value << std::endl;
}
Bench 212 Posting Pro

Are you talking about C++ strings or C-style char arrays? (I assume you're talking about char arrays, based on your post)

What do you mean by "completely empty"?

You can make a C++ string blank by doing this

std::string name = "hello";
std::cout << name;

//Assign 'name' a blank string
name = ""; 
std::cout << name;

for a C-style char array, you could do this

char name[20] = "fred";
std::cout << name;

//If the first character is a null terminator, the string is 'empty'.
name[0] = '\0' ;
std::cout << name;

Or do you wish to iterate through every element and set each one to zero? (You can do that with a loop, although there's not much point.)

Allen Jay commented: this is the most helpful one +0
Bench 212 Posting Pro

Maybe i'm unclear of the question.. but a number is just a number - you can use it to represent whatever you want. There's nothing particulary special about your 32 bit max value.. some systems can handle more, other systems can handle less, although, if you get hold of a "big number" library for C++, there's theoretically no maximum number. (C++ unfortunately has no built-in support for numbers of unlimited size, and relies on 3rd party libraries - other programming languages do however)

Incidentally, in C++, you can find the largest and smallest numbers that a type can hold using a feature of the standard library called numeric_limits. If you use different types inbetween the < and > - you'll see that max/min values of types varies wildly.

#include <iostream>
#include <limits>

int main()
{
    int max = std::numeric_limits<int>::max();
    int min = std::numeric_limits<int>::min();

    std::cout << "Maximum value for an int is: " << max << std::endl;
    std::cout << "Mainimum value for an int is: " << min << std::endl;
}

Of course, systems do have hard limits somewhere. on a 32-bit platform, 4-billion(ish) is the maximum number of addressable memory locations, because address values are only 32 bits wide. Is this what you were referring to?


Also, I suggest you stay away from any book written by Herbert Schildt. Every review of his books i've ever seen suggests that he hasn't got a clue about the languages he attempts to teach - his books are …

SpS commented: Rightly Said About Herbert Schildt +4
Bench 212 Posting Pro

if you want to retrieve an entire line from a stream (such as cin, or a file), then you need the getline function

string temp;
 getline( cin, temp );

Edit- by the way, if you use cin >> you need to be careful, because it comes with a few pitfalls, such as leaving newlines in the stream, and needing to be checked for errors.

A better way is to always read your input as a string using getline and convert from a string to a number using stringstream's

you may want to try something like this

//Retrieve an int from an input stream
int get_int( istream& is )
{
    string input;
    int output;
    while (true)
    {
        //Read a whole line of text from the input stream
        getline( is, input );
        stringstream ss(input);

        //If the input is an int, break out of the loop
        if( ss >> output )
            break;
        else
            cout << "Error\n";
    }
    return output;
}

int main() 
{
    cout << "enter a number: ";

    //Get an int from 'cin' - No need to worry about error flags or rogue newline's
    cout << get_int( cin );
}
Bench 212 Posting Pro

i dont know how to write this code..anyone can help me ?? here are the question :

Write a complete program that calculates the wages of an employee for the month(hint : input from user includes year,month,time in/time out for each day in that month.).

monday-friday :first 8hrs,Rm50......add.hour RM10/hr.
saturday and sunday:RM20/hr

thank you..

Which bits do you know how to write? Try to get as far as you can, and post your attempt. If you're having trouble with the logic of the program, try working out the calculations step-by-step on paper from a human perspective - this might make it easier to think about what steps the program needs to do the same, and what variables & calculations are involved.

Bench 212 Posting Pro

you don't need to take value_type out, just make sure the name is fully qualified when using it outside of the class, ie,

[b]node::[/b]value_type node::get_data() const
Bench 212 Posting Pro

yeah i use struct in C but not in C++ though it supports for struct.

In which case, you're probably aware of how handy it is to be able to group data together in a struct with your own data type. The idea of a class extends the concept of organising data in this way by throwing functions into the mix.

for example, if you've ever created a struct in a 'C' program, you've probably ended up with something like this in a header file

typedef struct
{
    int i;
    char* str;
    int size;
} my_type;

void do_something(my_type*);
void something_else(my_type*);
int another_function(my_type*);

The functions which accept a pointer to my_type are all designed to do something with a my_type object, So why not strengthen that relationship? - this is what classes do!

With a class, you could re-write that bit of C code like this

class my_type
{
    int i;
    char* str;
    int size;
public:
    void do_something();
    void something_else();
    int another_function();
};

The benefit here is that you no longer need to pass a my_type pointer to any of those functions, because each function is directly associated with my_type, and has one-to-one access with other data members of my_type.

classes bring up huge numbers of design issues, which opens up a whole new world of designing programs. These issues are best examined from a high-level OOP/OO-Design perspective (And i strongly reccomend reading up on OO Design) - which introduces ideas that may be unfamiliar to …

SpS commented: Good ~SpS +3
Bench 212 Posting Pro

First thing I suggest doing, is looking at this bit of your program carefully

enum SquareState
{
(blank = 's',
X = 'X',
0 ='0')
};

If you can't spot the errors, do some reading about enums

Ancient Dragon commented: absolutely agree with that approach. +15
Bench 212 Posting Pro

completely incorrect. the current version of turbo c++ (the free version is now called 'Turbo C++ Explorer') does support standard ANSI C and ISO/IEC C++ languages and libaries.

From what i've seen, the chance is, anyone posting here claiming to use "turbo C", is most probably referring to the original Borland turbo C from the early/mid 90s, rather than the modern version you linked to. In which case, jbennet is spot on.

~s.o.s~ commented: Bingo. +25
Bench 212 Posting Pro

Posting a block of code followed by a request of "please make me the rest of the code" doesn't constitute making an effort. Please don't expect others to finish it off for you.

If you've run in to a problem with code you've already written, then by all means, ask a question here, or show that you've made an attempt at the rest of your assignment and someone will help you with that. But noone will just spoon-feed you with large chunks of code, so that you can pretend to your tutor that you've done all your own homework.

Ancient Dragon commented: you're right +18
Bench 212 Posting Pro

Don't use atoi() - here's how to do it in C++

#include <sstream>
#include <iostream>

int main()
{
    const char* foo("1234");
    std::stringstream ss(foo);
    int i;
    if( ss >> i )
        std::cout << "i is: " << i ;
    else
        std::cout << "error";
}

The reason for using stringstreams is that your conversion will fail if the string contains anything which can't be converted to an int - which, if you're dealing with user input, is a real problem. if you use a stringstream, you can detect the error, without it messing up the rest of the program.

Killer_Typo commented: great post +6
Bench 212 Posting Pro

You don't need to use switch at all, try the STL map container instead, where you can link strings to other strings (just like in a dictionary)

Salem commented: A map would be good, if the OP is that far into the course :) +9
Bench 212 Posting Pro

Polymorphism occurs because of dynamic binding, which is made possible through use of pointers (The compiler internally represents a virtual function as a pointer, whose value is determined at run time) -

however, a static function is just that - its not a function pointer, but an object which has a static address.

If you want to call a derived class static function through a base class pointer, then you can use a non-static virtual function wrapper to achieve the same thing. eg,

#include <iostream>

class Base
{
    static void foo() { std::cout << "Base\n"; }
public:
    virtual void bar() { foo(); }

};

class Derived : public Base
{
    static void foo() { std::cout << "Derived\n"; }
public:
    virtual void bar() { foo(); }
};

int main()
{
    Base* obj = new Derived;
    obj->bar();
    delete obj;
}
Bench 212 Posting Pro
iamthwee commented: Too right! +12
Bench 212 Posting Pro

A couple of ways - which are explained by this link far better than I could.

http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.11

Bench 212 Posting Pro

You're getting confused between two very distinct topics in C/C++ - Pointers, and function pointers, which are both a rather different kettle of fish.

The reason that function pointers can be handled in such a way as shown in your original post is because of the nature of functions themselves.
in C/C++, you can really only do two things with a function - you may call it, or you may take its address.

Contrast this with a variable, you may also take its address, but you may not call it. In addition to this, unlike functions, you can assign to it, and you can obtain the data it stores.

Since functions and variables are so different, it follows that a pointer-to-function behaves differently to a pointer-to-variable.


Just to put the above into context, when you use the name (identifier) of a function, without the trailing parentheses, the compiler already knows that the function cannot have a value stored, therefore the address of the function is returned instead - the & (address-of) operator is unnecessary.

When you use the name/identifier of a variable, the compiler assumes you wish to obtain its stored value. Hence, if you wish to obtain the address of a variable you must explicitly use the '&' (address-of) operator.


The example you posted using the * (dereference) operator is not legal for the same reasons listed above. this is - a function has no stored data value, …

Salem commented: Nicely put +7
~s.o.s~ commented: Good one. +19
Bench 212 Posting Pro

I have to put the following block of code in a loop. It is to display a 10x10 array that will hold char values for a message encrypted in a transposition cipher.

I have not been able to figure out a loop or a system of loops that can do this. I need to do the loop for 10x10, 5x20, and 4x25, and 2x50. The snippet below is for 10x10, but if I can figure out how to do it for 10x10, I imagine it should be easy to do the other array dimensions too.

Have a close look at the repeated patterns in that code you've just pasted.

Remember that a 'for' loop is for repetition. Any code inside that loop is typically repeated a set number of times.
Try creating a for-loop that counts from 0 to 9 ..... (It will repeat 10 times)
- How would you repeat that for-loop, so that the loop itself gets executed 10 times..?

Bench 212 Posting Pro

That's odd - if intellisense is telling you that there's no information available, that suggests its not been disabled (I'm not even sure if you can disable it anyway) I'd suspect either a bug in MSVC++, or something has gone wrong with intellisense's lookup (maybe its database has gotten corrupted somehow?)

Sometimes in MSVC++ 2003 it gets confused by template template types (Especially if you manage to make a typo), and that can cause it to stop working, but usually only temporarily.

Maybe it would be worth creating a whole new Win32 Console project, just in case something 'weird' has happened to your current one. Try writing a 'hello world' app or something simple just to see if it works in there.

JoBe commented: Very helpfull +3
Bench 212 Posting Pro

Are you sure you've actually got an internal speaker? Not all motherboards have a connector for it. (Does your computer make a beep when you turn it on..?)

John A commented: You think of everything... -joeprogrammer +4
Bench 212 Posting Pro

The problem is probably Borland 3.1 - I see no reason why this code shouldn't compile in either C or C++ (it worked fine using Comeau online in strict mode).

I would reccomend talking to your teacher and asking why you are being taught an outdated version of the language (Borland 3.1 doesn't support many of the features which are a part of today's standard C++)

Aside from this, what exactly requires you to use so many global variables? there is more than likely another way to redesign your program without using global variables at all.

SpS commented: Right Advice ~~ SpS +3
Bench 212 Posting Pro

In trying to map a network drive from "My Computer" and then "Map Drive", it's not finding my shared folder on my old laptop. Basically I'm trying to map a drive on my new laptop to the "C" drive on my old laptop to share data between them.
I know that my old laptop is named "JohnsLaptop" and the shared "C" drive is named C$. The "C" drive has the little hand under it, so I know it's being shared. However, it doesn't show up when I browse for it or when I type it in explicitly. I'm typing
\\JohnsLaptop\C$

Any ideas?

From what I recall, you can't use the C$ "default share" in order to share a drive - you'll need to create a new share and use that instead. My best guess is that C$ is something to do with resource sharing for local users rather than remote ones.

Roobyroo commented: Helpful +1
Bench 212 Posting Pro

What do you mean by "on screen"? do you mean..

  • Output spanning the entire screen?
  • In a window?
  • Across the command-prompt background?
  • On the screen of a PDA/Phone or other mobile device?
  • Something else?

Standard C/C++ has no concept of BMP files, nor any kind of video display output (Nor anything else that can be deemed implementation-specific)
- Depending on your O/S and compiler, you may already have libraries which are capable of handling these kinds of tasks, otherwise you'll need to download some 3rd party APIs

Bench 212 Posting Pro

For a crossover cable:

End 1 : T568A

Pin 1 - Orange/White
Pin 2 - Orange
Pin 3 - Green/White
Pin 4 - Blue
Pin 5 - Blue/White
Pin 6 - Green
Pin 7 - Brown/White
Pin 8 - Brown


End 2 : T568B

Pin 1 - Green/White
Pin 2 - Green
Pin 3 - Orange/White
Pin 4 - Blue
Pin 5 - Blue/White
Pin 6 - Orange
Pin 7 - Brown/White
Pin 8 - Brown

Pins 1 and 2 are Tx (Transmit), while Pins 3 and 6 are Rx (Recieve) - So make sure Pin1 connects to Pin3, and Pin2 connects to Pin6. Don't just use any old colour either - the reason for the colours being in the order they are, is that the colours match the twisted pairs inside the UTP cable. (the twists are there deliberately to cancel out crosstalk)

Be careful when crimping the ends - Make sure there's only just enough of the jacket stripped for the wires to firmly make contact with the RJ45 pins - too little and there'll be no connection... too much, and your cable will suffer from excessive Crosstalk (NEXT).

If initially you strip off too much of the jacket, you can trim the wires with a pair of scissors, use the the RJ45 plug as a guide to the length you'll need

See here …