Results 1 to 10 of 10
  1. #1
    Join Date
    Dec 2012
    Location
    the Netherlands, Breda
    Posts
    5

    Angry C++ Class Tutorial & Codeblocks Issue

    Hi there, my name is John and I have been checking out the C++ learning section for the last couple of days.
    Today I am working on C++ classes. But while trying to comprehend what is being taught by playing with it myself, I stumbled upon some weird situation.

    I created the class "Point" as shown in the video. Inside the class Point I defined 2 constructors.

    Code:
    class Point{
        public:
            Point(float x = 0.0, float y = 1.0, float z = 0.0);
            Point();
        private:
            float x, y, z;
    
        protected:
    };
    I did initiate both constructors above the 'main' function:

    Code:
    Point::Point(float x, float y, float z)
    {
        cout << "We're in the constructor with arguments." << endl;
    }
    
    Point::Point()
    {
        cout << "This is the default constructor." << endl;
    }
    main function

    Code:
    int main()
    {
        Point myLocation(0,0,0);
        Point coffee();
        return 0;
    }
    Compiling goes without any error, but whenever I run the program it only shows the constructor cout with arguments.
    It somehow completely ignores the default constructor output.

    Any idea on what might be going wrong?
    I am using Codeblocks latest version.

    Also, the compiler does not let me change the data-type of main to void. It must remain int.

    Thanks in advance,

    John

  2. #2
    Join Date
    Jun 2003
    Location
    Trier, Germany
    Posts
    1,350
    Quote Originally Posted by natoxic View Post
    Compiling goes without any error, but whenever I run the program it only shows the constructor cout with arguments.
    It somehow completely ignores the default constructor output.
    Your overloading is flawed. Suppose you just had the first constructor:
    Code:
    Point(float x = 0.0, float y = 1.0, float z = 0.0);
    Then all of the following are valid:
    Code:
    Point p1(5.0, 4.0, 3.0);   // creates a point (5,4,3)
    Point p2(5.0, 4.0);         // creates a point (5,4,0)
    Point p1(5.0);               // creates a point (5,1,0)
    Point p0;                      //creates a point (0,1,0)
    Due to default arguments, you don't need a default constructor at all! If you now add one anyway would introduce an ambiguity on the last line, because both the default constructor and the 3-param constructor with default arguments match. Just one of the many dangers of default arguments. I usually avoid using them at all (explicit overloads 4tw!), but if you insist, at least make sure you don't introduce ambiguities.

    Now, why did this compile at all in your code? And this is where the fun starts.
    Code:
    Point p0;
    Point not_a_point_at_all();
    The first creates a point using the default constructor. The second declares a function returning a Point under the name not_a_point_at_all.

    Unintuitive? Hell yes, that's why people also call it the most-vexing parse of C++.

    Also, the compiler does not let me change the data-type of main to void. It must remain int.
    That's because void main is not valid C++. Shame on the C++ VTMs for not acknowledging that (earlier versions of Visual C++ allowed the non-standard void main, but that has been fixed by now).
    Last edited by ComicSansMS; 12-12-2012 at 09:22 AM.

  3. #3
    Join Date
    Dec 2012
    Location
    the Netherlands, Breda
    Posts
    5
    Thank you so much for this fast reply! :-) It kinda makes sense now (still alot of information to process)....

    So I tried the following and now it does work! :-)

    #include <iostream>
    using namespace std;

    class Point{
    public:
    Point(float x, float y, float z);
    Point();

    private:
    float x, y, z;

    protected:
    };


    Point::Point(float x, float y, float z)
    {
    cout << "We're in the constructor with arguments." << endl;
    }

    Point::Point()
    {
    cout << "This is the default constructor." << endl;
    }

    int main()
    {
    Point myLocation(0,0,0);
    Point coffee;

    return 0;
    }
    So the 3-param constructor was trying to force the default values onto what I thought was the default constructor call?


    These educational videos here are still kinda confusing sometimes.
    I'm a mere beginner when it comes to programming ( have some HTML / CSS experience ) ... but I will understand some day!

  4. #4
    Join Date
    Sep 2010
    Location
    Gateshead, UK
    Posts
    77
    Hi John, I'm also trying to learn c++ by following the c++ VTM's but found the classes vtm really confusing. I was having the same issues as you when attempting to use the default constructor so big thanks to Comic Sans for identifying the error. Still I'll need to rewatch the VTM to get a better understanding of classes before I move onto inheritence. Also a bit cloudy on the difference between classes and structs.
    "I aim to misbehave"

  5. #5
    Join Date
    Jun 2003
    Location
    Trier, Germany
    Posts
    1,350
    Quote Originally Posted by natoxic View Post
    So the 3-param constructor was trying to force the default values onto what I thought was the default constructor call?
    Not quite, in you code there was no 'coffee' Point at all, due to the parentheses on that line. If you had omitted the parentheses the compiler would have complained because of the ambiguous constructor call. So it was really 2 mistakes in the code, the obvious one (default parameters) and a more subtle one (the most vexing parse due to the parentheses), where the subtler one masked the obvious one.


    I'm a mere beginner when it comes to programming ( have some HTML / CSS experience ) ... but I will understand some day!
    Hang in there! It does take some years to get comfortable with C++, but that's part of the fun

    Quote Originally Posted by Scimac View Post
    Also a bit cloudy on the difference between classes and structs.
    Members of class are private by default, for struct it's public by default. That's *all*.

    There is a convention among certain programmers to use struct for plain-data, c-style records but this is a mere coding convention and in no way supported by the language. This is mainly for historical reasons, since C already knew struct, but it was far less powerful than its C++ counterpart. Grab a good C textbook if you want to know more.

  6. #6
    Join Date
    Dec 2012
    Location
    the Netherlands, Breda
    Posts
    5
    Quote Originally Posted by Scimac View Post
    Hi John, I'm also trying to learn c++ by following the c++ VTM's but found the classes vtm really confusing. I was having the same issues as you when attempting to use the default constructor so big thanks to Comic Sans for identifying the error. Still I'll need to rewatch the VTM to get a better understanding of classes before I move onto inheritence. Also a bit cloudy on the difference between classes and structs.
    Hey Scimac! It is quite confusing... but it's definitely worth it I believe! :-) Good thing ComicSansMS was able to help us both within this thread then aye.. ;-)

    By the way, try not to stick 'only' to these VTM's on 3Dbuzz... there's some other really good ones out there... and the more VTM's you see from different people that have different ways of explaining their perspective... the more you'll learn! I'm not really sure if I can show you what other communities I'm using, but if you want to know, just send me a PM. :-)

    Goodluck on the learning but most important, enjoy it!

  7. #7
    Join Date
    Dec 2012
    Location
    the Netherlands, Breda
    Posts
    5
    Not quite, in you code there was no 'coffee' Point at all, due to the parentheses on that line. If you had omitted the parentheses the compiler would have complained because of the ambiguous constructor call. So it was really 2 mistakes in the code, the obvious one (default parameters) and a more subtle one (the most vexing parse due to the parentheses), where the subtler one masked the obvious one.
    Haha, I'm sorry for being such a pain in the butt... :-) but I'm trying to comprehend.

    So because of the fact that I was using default values in the 3 parameters of that constructor, the first call:

    Point myLocation(0,0,0);

    was being recognized by the 3-param constructor. So, coffee(); would be recognized if it had 1, 2 or 3 values inside the parentheses like "coffee(1.0);". But since it had none, it was actually behaving like a function instead? (because of the (); ).
    And because a Point coffee; would also be a valid entree of the 3-parameter constructor (because it has default values) it would be in conflict with the 'default' empty constructor?

  8. #8
    Join Date
    Jun 2003
    Location
    Trier, Germany
    Posts
    1,350
    Quote Originally Posted by natoxic View Post
    Haha, I'm sorry for being such a pain in the butt... :-) but I'm trying to comprehend.

    So because of the fact that I was using default values in the 3 parameters of that constructor, the first call:

    Point myLocation(0,0,0);

    was being recognized by the 3-param constructor. So, coffee(); would be recognized if it had 1, 2 or 3 values inside the parentheses like "coffee(1.0);". But since it had none, it was actually behaving like a function instead? (because of the (); ).
    And because a Point coffee; would also be a valid entree of the 3-parameter constructor (because it has default values) it would be in conflict with the 'default' empty constructor?
    Exactly.

    The problem here is that if you want to declare a function of name coffee, taking no arguments and returning a Point you *have* to write Point coffee();, there is no other way of saying this. That's why this interpretation is always preferred by the compiler.

  9. #9
    Join Date
    Dec 2012
    Location
    the Netherlands, Breda
    Posts
    5
    Quote Originally Posted by ComicSansMS View Post
    Exactly.

    The problem here is that if you want to declare a function of name coffee, taking no arguments and returning a Point you *have* to write Point coffee();, there is no other way of saying this. That's why this interpretation is always preferred by the compiler.
    Well thank you so much, you made me understand this alot better!

  10. #10
    Join Date
    Sep 2010
    Location
    Gateshead, UK
    Posts
    77
    Quote Originally Posted by natoxic View Post
    Hey Scimac! It is quite confusing... but it's definitely worth it I believe! :-) Good thing ComicSansMS was able to help us both within this thread then aye.. ;-)

    By the way, try not to stick 'only' to these VTM's on 3Dbuzz... there's some other really good ones out there... and the more VTM's you see from different people that have different ways of explaining their perspective... the more you'll learn! I'm not really sure if I can show you what other communities I'm using, but if you want to know, just send me a PM. :-)

    Goodluck on the learning but most important, enjoy it!
    Thanks I've also got two books to work through, Beginning C++ through Game Programming and Sams Teach Yourself C++ in One Hour a Day. I've also been watching the Spoonfed Noob series on youtube.
    "I aim to misbehave"

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •