Thread: Learning C++ by Example

  1. #106
    Registered User
    Join Date
    Nov 2010
    Posts
    122
    Quote Originally Posted by Elysia View Post
    The only book that, at least somewhat, learns and teaches C++11 that I know of is this one.
    I have this one.

    How did you learnt?

  2. #107
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by marcoesteves View Post
    How did you learnt?
    I taught myself. At least one book in the early, though.
    After that... web resources and this forum. My knowledge of C++11 comes from keeping up to the standard and reading documentation and googling to find explanations and examples.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #108
    Registered User
    Join Date
    Nov 2010
    Posts
    122
    I know, I'm stubborn, but there is my updated code with printing enable.

    Code:
    #include <iostream>
    #include <vector>
    #include <string>
    
    
    
    class XTrackInfo
    {
        std::string m_TrackName;
        int m_Length;
    
    public:
        XTrackInfo() {}
    
        XTrackInfo(std::string TrackName, int Length):
            m_TrackName(std::move(TrackName)),
            m_Length(Length)
        {}
    
        void SetTrackName(std::string TrackName) { m_TrackName = std::move(TrackName); }
        void SetTrackLength(int Length) { m_Length = Length; }
        const std::string& GetTrackName() const { return m_TrackName; }
        int GetTrackLength() const { return m_Length; }
    };
    
    class XMusicCd
    {
    private:
        // You may not modify these member variables
        std::string m_Author;
        std::vector<XTrackInfo> m_TrackInfo;
    
    public:
        // You may not modify these member functions
        XMusicCd() {}
        XMusicCd(std::string Author, std::vector<XTrackInfo> Tracks):
            m_Author(std::move(Author)),
            m_TrackInfo(std::move(Tracks))
        {}
    
        void SetAuthor(std::string Author) { m_Author = std::move(Author); }
    
        const std::string& GetAuthor() const { return m_Author; }
        const std::vector<XTrackInfo>& GetTracks() const { return m_TrackInfo;}
    
        int GetLength() const {}
    
    
        void AddTrack(XTrackInfo NewTrack){
    
            m_TrackInfo.emplace_back(std::move(NewTrack));
    
        }
    
    
    };
    
    
    
    void PrintCdContents(const XMusicCd& Cd)
    {
        std::cout << "Author : " << Cd.GetAuthor() << "\n";
        std::cout << "\n" << std::endl;
        std::cout << "Track Info" << std::endl;
    
    
        std::vector<XTrackInfo> tracks = Cd.GetTracks();
        for (std::vector<XTrackInfo>::const_iterator it = tracks.begin(); it != tracks.end(); ++it) {
            std::cout << it->GetTrackName() << std::endl;
            std::cout << it-> GetTrackLength() << std::endl;
        }
    
    
    }
    
    int main()
    {
        // You may not change this function
        XMusicCd MyCd;
        MyCd.SetAuthor("Hello World");
        MyCd.AddTrack(XTrackInfo("This is a test", 100));
        MyCd.AddTrack(XTrackInfo("This is a test 2", 200));
      //  MyCd.GetLength();
        PrintCdContents(MyCd);
    }
    I've got some doubts. I think should be a smarter way to use the iterators. For instance without creating the:
    Code:
        std::vector<XTrackInfo> tracks = Cd.GetTracks();
    Is there a way to pass the reference instead the object?

    It remains one function to code
    Code:
       int GetLength() const {}
    This is function is inside XMusicCD class . So, if I were able to use the reference instead the object, i can use iterators to sum all of lengths of tracks which belong to the particular Cd object. Right?

    I want to avoid using static variables. They are easy to use, but bad programming practice.

  4. #109
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by marcoesteves View Post
    I've got some doubts. I think should be a smarter way to use the iterators. For instance without creating the:
    Code:
        std::vector<XTrackInfo> tracks = Cd.GetTracks();
    Is there a way to pass the reference instead the object?
    Use a reference:
    Code:
        std::vector<XTrackInfo>& tracks = Cd.GetTracks();
    Or better yet,
    Code:
        auto && tracks = Cd.GetTracks();
    Code:
        for (std::vector<XTrackInfo>::const_iterator it = tracks.begin(); it != tracks.end(); ++it) {
            std::cout << it->GetTrackName() << std::endl;
            std::cout << it-> GetTrackLength() << std::endl;
        }
    Since you wish to learn about C++11...
    Code:
        for (auto && elem : tracks)
    {
            std::cout << elem.GetTrackName() << std::endl;
            std::cout << elem.GetTrackLength() << std::endl;
        }
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #110
    Registered User
    Join Date
    Nov 2010
    Posts
    122
    Quote Originally Posted by Elysia View Post
    Use a reference:
    Code:
        std::vector<XTrackInfo>& tracks = Cd.GetTracks();
    Or better yet,
    Code:
        auto && tracks = Cd.GetTracks();
    Code:
        for (std::vector<XTrackInfo>::const_iterator it = tracks.begin(); it != tracks.end(); ++it) {
            std::cout << it->GetTrackName() << std::endl;
            std::cout << it-> GetTrackLength() << std::endl;
        }
    Since you wish to learn about C++11...
    Code:
        for (auto && elem : tracks)
    {
            std::cout << elem.GetTrackName() << std::endl;
            std::cout << elem.GetTrackLength() << std::endl;
        }
    C++11 has an easier implemenation, but harder to understand 1st time.

    Now, I'm concerned about:
    Code:
    int GetLength() const;
    This functions must get the sum of all lenghts.
    First at all, how do you (Elysia) declare as const ? If the value changes, shouldn't have const?

    This is a mutation function of XMusicCD class. I'm not figuring out how can I access the TracKObjects, if they aren't created at this point (If I'm not wrong).
    I'm assuming that you are correct, but I think this function can be global and use static members. On the other hand, static variables aren't a good programming pratice.

  6. #111
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by marcoesteves View Post
    C++11 has an easier implemenation, but harder to understand 1st time.
    On the contrary,
    auto && tracks = Cd.GetTracks();
    means simply "hey, compiler, deduce the type for me so I don't have to spell it."
    Two ampersands instead of one has to do with r-value references, so just take it as standard practice when it comes to using the keyword auto. auto and double ampersands go together. Look into "universal references" if you want to know more.

    Now this:
    for (auto && elem : tracks)
    simply means: hey, give me every element in tracks and for each element in tracks, store a reference to it in elem.
    Plain, simple, intuitive.

    Now, I'm concerned about:
    Code:
    int GetLength() const;
    This functions must get the sum of all lenghts.
    First at all, how do you (Elysia) declare as const ? If the value changes, shouldn't have const?
    The function is const, not the variable. That means the function cannot change any member variables or call non-const functions. Look up the meaning of const.

    This is a mutation function of XMusicCD class.
    No, it's not a mutation function. Getting the length does not require "mutating" any class state.

    I'm not figuring out how can I access the TracKObjects, if they aren't created at this point (If I'm not wrong).

    I'm assuming that you are correct, but I think this function can be global and use static members. On the other hand, static variables aren't a good programming pratice.
    A global function with static members? I don't see how that would ever work, so if you think you can pull it off, then go ahead and try. You should see why it can't be pulled off.
    You're right. The function can be global, but I want you think about member state (i.e. member variables and *this).
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #112
    Registered User
    Join Date
    Nov 2010
    Posts
    122
    Quote Originally Posted by Elysia View Post

    A global function with static members? I don't see how that would ever work, so if you think you can pull it off, then go ahead and try. You should see why it can't be pulled off.
    You're right. The function can be global, but I want you think about member state (i.e. member variables and *this).

    I think that I'm understanding. However I've searched on references about *this pointer and I'm not figuring out how to using. I've only found examples which not fit. The most interesting that I found was:

    C++ this Pointer

    GetLenght "needs" to access the value of trackinfo lenght.
    In XMusicCD it's possible access the accessor functions of XTrackInfo. However, I think that we cannot use iterators since we're not sure if there is an object.
    Or on the other hand it can be possible use an argument in GetLenght;

    There is my code updated with a global function:
    Code:
    #include <iostream>
    #include <vector>
    #include <string>
    
    
    
    class XTrackInfo
    {
        std::string m_TrackName;
        int m_Length;
    
    public:
        XTrackInfo() {}
    
        XTrackInfo(std::string TrackName, int Length):
            m_TrackName(std::move(TrackName)),
            m_Length(Length)
        {}
    
        void SetTrackName(std::string TrackName) { m_TrackName = std::move(TrackName); }
        void SetTrackLength(int Length) { m_Length = Length; }
    
        const std::string& GetTrackName() const { return m_TrackName; }
        int GetTrackLength() const { return m_Length; }
    };
    
    class XMusicCd
    {
    private:
        // You may not modify these member variables
        std::string m_Author;
        std::vector<XTrackInfo> m_TrackInfo;
    
    public:
        // You may not modify these member functions
        XMusicCd() {}
        XMusicCd(std::string Author, std::vector<XTrackInfo> Tracks):
            m_Author(std::move(Author)),
            m_TrackInfo(std::move(Tracks))
        {}
    
        void SetAuthor(std::string Author) { m_Author = std::move(Author); }
    
        const std::string& GetAuthor() const { return m_Author; }
        const std::vector<XTrackInfo>& GetTracks() const { return m_TrackInfo;}
    
    //    int GetLength(XMusicCd Cd) const{
    
    //    }
    
    
        void AddTrack(XTrackInfo NewTrack){
    
            m_TrackInfo.emplace_back(std::move(NewTrack));
    
        }
    
    
    };
    
    void CalcTotalLen(const XMusicCd& Cd){
        int sum=0;
        auto && MyTracks = Cd.GetTracks();
    
        for (auto && elem : MyTracks)
        {
            sum+= elem.GetTrackLength();
    
        }
        std::cout << "total len: "<< sum << std::endl;
    
    }
    
    
    void PrintCdContents(const XMusicCd& Cd)
    {
        std::cout << "Author : " << Cd.GetAuthor() << "\n";
        std::cout << "\n" << std::endl;
        std::cout << "Track Info" << std::endl;
    
    
        //std::vector<XTrackInfo> tracks = Cd.GetTracks();
         auto && MyTracks = Cd.GetTracks();
    
    //    for (std::vector<XTrackInfo>::const_iterator it = tracks.begin(); it != tracks.end(); ++it) {
    //        std::cout << it->GetTrackName() << std::endl;
    //        std::cout << it-> GetTrackLength() << std::endl;
    //    }
    
         for (auto && elem : MyTracks)
         {
                 std::cout << elem.GetTrackName() << std::endl;
                 std::cout << elem.GetTrackLength() << std::endl;
         }
    
    
    }
    
    int main()
    {
        // You may not change this function
        XMusicCd MyCd;
        MyCd.SetAuthor("Hello World");
        MyCd.AddTrack(XTrackInfo("This is a test", 100));
        MyCd.AddTrack(XTrackInfo("This is a test 2", 200));
        PrintCdContents(MyCd);
        CalcTotalLen(MyCd);
    }

  8. #113
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by marcoesteves View Post
    I think that I'm understanding. However I've searched on references about *this pointer and I'm not figuring out how to using. I've only found examples which not fit. The most interesting that I found was:

    C++ this Pointer

    GetLenght "needs" to access the value of trackinfo lenght.
    In XMusicCD it's possible access the accessor functions of XTrackInfo. However, I think that we cannot use iterators since we're not sure if there is an object.
    Or on the other hand it can be possible use an argument in GetLenght;
    Look at this code:
    Code:
    class A
    {
    public:
    	void foo() { std::cout << "My address is    " << this << ", and my bar value is  " << bar << "\n"; } // this->bar also works
    	int bar = 0;
    };
    
    int main()
    {
    	A A1, A2;
    	
    	A1.bar = 10;
    	A2.bar = 20;
    	
    	std::cout << "Address of A1 is " << &A1 << ", and its bar value is " << A1.bar << "\n";
    	A1.foo();
    
    	std::cout << "Address of A2 is " << &A2 << ", and its bar value is " << A2.bar << "\n";
    	A2.foo();
    }
    Run it. Print it. Examine it.

    You see that class A has a variable bar. But as we have TWO A objects, we have TWO bar variables. So how does A::foo know which bar variable whose value it should print? Simply put, the "this" keyword.
    If you run it, you will see that "this" equals the value of the address of the object. In other words, we can see

    A1.foo();
    as being the same as
    foo(&A1);

    Which leads us to that in reverse, that means

    foo(&A1);
    is the same as
    A1.foo();

    So you wrote

    auto && MyTracks = Cd.GetTracks();
    This, then, can implicitly be thought of as
    auto && MyTracks = GetTracks(&Cd);
    Which implies that in XMusicCd::GetTracks, "this" == &Cd.

    So I ask you: in XMusicCd::GetLength(), how would you acquire the tracks object?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #114
    Registered User
    Join Date
    Nov 2010
    Posts
    122
    Quote Originally Posted by Elysia View Post
    Look at this code:

    So I ask you: in XMusicCd::GetLength(), how would you acquire the tracks object?
    Code:
    int GetLenght(const XMusicCd Cd) const
    ?

  10. #115
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    No, you miss the point.
    Code:
    int XMusicCd::Getlength() const
    {
        auto && Tracks = ???;
    }
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  11. #116
    Registered User
    Join Date
    Nov 2010
    Posts
    122
    Quote Originally Posted by Elysia View Post
    No, you miss the point.
    Code:
    int XMusicCd::Getlength() const
    {
        auto && Tracks = ???;
    }

    Now I get it:
    Code:
        int GetLenght() const{
    
            int sum=0;
    
            auto && MyTracks = this->GetTracks();
    
            for (auto && elem : MyTracks)
            {
                sum+= elem.GetTrackLength();
    
            }
    
        return sum;
        }

  12. #117
    Registered User
    Join Date
    Nov 2010
    Posts
    122
    I've updated my code and I have a few questions:

    Code:
    #include <iostream>
    #include <vector>
    #include <string>
    
    
    
    class XTrackInfo
    {
        std::string m_TrackName;
        int m_Length;
    
    public:
        XTrackInfo() {}
    
        XTrackInfo(std::string TrackName, int Length):
            m_TrackName(std::move(TrackName)),
            m_Length(Length)
        {}
    
        void SetTrackName(std::string TrackName) { m_TrackName = std::move(TrackName); }
        void SetTrackLength(int Length) { m_Length = Length; }
    
        const std::string& GetTrackName() const { return m_TrackName; }
        int GetTrackLength() const { return m_Length; }
    };
    
    class XMusicCd
    {
    private:
        // You may not modify these member variables
        std::string m_Author;
        std::vector<XTrackInfo> m_TrackInfo;
    
    public:
        // You may not modify these member functions
        XMusicCd() {}
        XMusicCd(std::string Author, std::vector<XTrackInfo> Tracks):
            m_Author(std::move(Author)),
            m_TrackInfo(std::move(Tracks))
        {}
    
        void SetAuthor(std::string Author) { m_Author = std::move(Author); }
    
        const std::string& GetAuthor() const { return m_Author; }
        const std::vector<XTrackInfo>& GetTracks() const { return m_TrackInfo;}
    
    
        void AddTrack(XTrackInfo NewTrack){
    
            m_TrackInfo.emplace_back(std::move(NewTrack));
    
        }
    
        int GetLenght() const{
    
            int sum=0;
    
            auto && MyTracks = this->GetTracks();
    
            for (auto && elem : MyTracks)
            {
                sum+= elem.GetTrackLength();
    
            }
    
        return sum;
        }
    
    
    
    
    };
    
    class XCollection
    {
        private:
    
        std::vector <XMusicCd> m_cdCollection;
    
        public:
        XCollection(){}
        XCollection(std::vector <XMusicCd> CdCollection):
        m_cdCollection(std::move(CdCollection))
        {}
    
        const std::vector <XMusicCd>& GetCds() const {return m_cdCollection;}
    
        void addCD(XMusicCd NewCD){
            m_cdCollection.emplace_back(std::move(NewCD));
        }
    
    
    
    };
    
    void CalcTotalLen(const XMusicCd& Cd){
        int sum=0;
        auto && MyTracks = Cd.GetTracks();
    
        for (auto && elem : MyTracks)
        {
            sum+= elem.GetTrackLength();
    
        }
        std::cout << "total len: "<< sum << std::endl;
    
    }
    
    void PrintCollectionContents(const XCollection& Collection){
        std::cout << "Cd number : " << "1" << "\n";
        std::cout << "Cd info : " << std::endl;
    
        auto MyCds = Collection.GetCds();
    
        for(auto && elem: MyCds){
            std::cout << elem.GetAuthor() << std::endl;
            //How can I acess the tracks of the particular cd ?
        }
    
    
    
    }
    
    void PrintCdContents(const XMusicCd& Cd)
    {
        std::cout << "Author : " << Cd.GetAuthor() << "\n";
        std::cout << "\n" << std::endl;
        std::cout << "Track Info" << std::endl;
    
    
        //std::vector<XTrackInfo> tracks = Cd.GetTracks();
         auto && MyTracks = Cd.GetTracks();
    
    //    for (std::vector<XTrackInfo>::const_iterator it = tracks.begin(); it != tracks.end(); ++it) {
    //        std::cout << it->GetTrackName() << std::endl;
    //        std::cout << it-> GetTrackLength() << std::endl;
    //    }
    
         for (auto && elem : MyTracks)
         {
                 std::cout << elem.GetTrackName() << std::endl;
                 std::cout << elem.GetTrackLength() << std::endl;
         }
    
    
    }
    
    int main()
    {
        // You may not change this function
        XMusicCd MyCd;
        MyCd.SetAuthor("Hello World");
        MyCd.AddTrack(XTrackInfo("This is a test", 100));
        MyCd.AddTrack(XTrackInfo("This is a test 2", 200));
        PrintCdContents(MyCd);
        CalcTotalLen(MyCd);
        std::cout << "total cd lenght: " << MyCd.GetLenght()<< std::endl;
    
        XCollection MyCollection;
        MyCollection.addCD(MyCd);
        PrintCollectionContents(MyCollection);
    
    }
    I want to implement a simple counter.
    When I add a cd to a particular collection, automatcly it makes sense it has a number.
    Do I need to use a static or global variable? Anytime that I emplace another cd I wanna count +1.

    Another question:

    I want to access the tracks of one particular cd. Can I use another for? I don't know which is the best way.

    Code:
    void PrintCollectionContents(const XCollection& Collection){
    std::cout << "Cd number : " << "1" << "\n";
        std::cout << "Cd info : " << std::endl;
    
        auto MyCds = Collection.GetCds();
    
        for(auto && elem: MyCds){
            std::cout << elem.GetAuthor() << std::endl;
            //How can I acess the tracks of the particular cd ?
        }
    
    }

  13. #118
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by marcoesteves View Post
    I want to implement a simple counter.
    When I add a cd to a particular collection, automatcly it makes sense it has a number.
    Do I need to use a static or global variable? Anytime that I emplace another cd I wanna count +1.
    Standard library containers automatically keep track of their size. You don't have to do anything like that.

    Another question:

    I want to access the tracks of one particular cd. Can I use another for? I don't know which is the best way.
    If you want to access only one specific element of the vector, take a look at the documentation:
    vector - C++ Reference
    Do you see a function that might be suitable?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  14. #119
    Registered User
    Join Date
    Nov 2010
    Posts
    122
    I didn't explain myself very well

    I think that is interesting when a cd is appended to the colllection a number be attributed to it.

    Example, when you have a collection with 2 cds, there is a CD 1 and a CD2, for instance.

    To acess the tracks of a particular cd which belongs to a collection I think that I need to use the operator [] .
    With size function I can get the tracks size of a particular cd, however I didn't find out how to properly create the "for-cycle".

  15. #120
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by marcoesteves View Post
    I didn't explain myself very well

    I think that is interesting when a cd is appended to the colllection a number be attributed to it.

    Example, when you have a collection with 2 cds, there is a CD 1 and a CD2, for instance.
    Unless you mean to name your CDs arbitrarily, you still don't need it.
    There are four ways to get a CD from a collection, two of which are interesting.
    The first way you iterate over all, by which you can keep track of which CD you're currently accessing either by using indices or using a helper variable.
    The second way is to get a specific CD by an index. But by knowing the index, you know what CD "number" it is.

    To acess the tracks of a particular cd which belongs to a collection I think that I need to use the operator [] .
    Bear in mind that operator [] causes undefined behavior if you access an index that does not exist. For that very reason, I strongly recommend against using it unless you really need the speed. Using the .at() function helps you more easily catch bugs where you access elements that do not exist.

    With size function I can get the tracks size of a particular cd, however I didn't find out how to properly create the "for-cycle".
    I don't know what you mean with "for-cycle."
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Learning C++
    By sLIVER in forum C++ Programming
    Replies: 2
    Last Post: 07-11-2007, 08:18 PM
  2. Learning
    By nojoegohome in forum C++ Programming
    Replies: 6
    Last Post: 07-06-2006, 04:33 AM
  3. Learning Dos and learning Windows
    By blankstare77 in forum C++ Programming
    Replies: 8
    Last Post: 07-31-2005, 03:48 PM
  4. Learning?
    By bob20 in forum A Brief History of Cprogramming.com
    Replies: 41
    Last Post: 12-11-2002, 10:17 AM

Tags for this Thread