Thread: Learning C++ by Example

  1. #61
    Registered User
    Join Date
    Nov 2010
    Posts
    122
    I'm reading the chapter 3 of C++ primer 5th edition book. I'll doing all exercises.
    I think that I know what the addTrack fcn will do. I don't know (yet) how to implement.

    AddTrack function should receive(from overloaded constructor) or create(using setters) a track object and append this object to the vector Tracks of xmusicCd.
    So, this is clear, but I think that I'm far way .

  2. #62
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by marcoesteves View Post
    AddTrack function should receive(from overloaded constructor) or create(using setters) a track object and append this object to the vector Tracks of xmusicCd.
    So, this is clear, but I think that I'm far way .
    Oh, come on. You said it yourself.
    The AddTrack function adds the track it receives to the collection of tracks it already has (i.e. the vector of tracks).
    This is as simple as it gets. Check the reference doc for std::vector.
    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. #63
    Registered User
    Join Date
    Nov 2010
    Posts
    122
    I think that i need to use emplace.However I don't know how can I access the Tracks vector.

  4. #64
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    All class member function are able to access the class's private variables.
    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. #65
    Registered User
    Join Date
    Nov 2010
    Posts
    122
    Ok, there is an update.
    I don't know how can I access the Trackinfo Vector inside of Cd class, could you help?

    I think the AddFunction is working, but I had to find how to to print to be sure.


    Code:
    #include <iostream>
    #include <vector>
    #include <string>
    
    // You may not modify XTrackInfo
    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; }
    
        int GetLength() const; // Left incomplete on purpose; you will implement it later
    
    
        void AddTrack(XTrackInfo NewTrack){
            m_TrackInfo.emplace_back(NewTrack.GetTrackName(),NewTrack.GetTrackLength());
    
        }
    
    
        // Add additional functions to this class as necessary to make it compile.
    };
    
    
    
    void PrintCdContents(const XMusicCd& Cd)
    {
        // Implement this function such that it compiles
        // Also, to be explicit, you may not add any tracks to the CD in here. That is not the purpose of this function. You may also not change the signature of the function.
        // You shall specifically not modify the CD object by calling any setters.
       //Cd.
    
        std::cout << "Author : " << Cd.GetAuthor() << "\n";
        std::cout << "\n" << std::endl;
        std::cout << "Track Info" << std::endl;
    //    for(auto && e: Cd.Tracks){
    //        std::cout << e << "\n";}
    
        // How can I acess the trackinfo vector inside of Cd class?
        //
    
    
    }
    
    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);
    }

  6. #66
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    I don't know how can I access the Trackinfo Vector inside of Cd class, could you help?
    You'll need to create a XMusicCd member function to provide access to that vector.



    Jim

  7. #67
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by marcoesteves View Post
    I don't know how can I access the Trackinfo Vector inside of Cd class, could you help?
    That's the problem, isn't it? Yes, you can look at the class and see "hey, there's a vector of tracks in there." But actually, you aren't supposed to know that because it's a so-called "implementation detail."
    The user of a class should not be concerned about how things are stored--actually, it should not be concerned with any of a class's private variables.
    Instead, you should be thinking: "Okay, so I know a Music CD contains an author and a collection of tracks" (because, by definition, a CD contains one or more tracks), "so, I need to access these tracks so I can print their information. How do I do that?"
    And I can give you a tip. We have the same problem with author, because we can't access the author directly inside the class either. In fact, we don't even know how the author is stored, and we don't care. Fortunately, there already is a function called GetAuthor already implemented. It is a function that is part of the class's interface that defines an operation we can do on it.
    So obviously, you need to implement another function in the class in order to access the information you need. But actually, there are two ways to do what you want. Consider the operations: "return a list of all tracks" and "print information of all tracks (for debugging purposes)". Both should suit what you need and it's up to you to implement one such function.

    I think the AddFunction is working, but I had to find how to to print to be sure.
    Or you can use a debugger.

    >>void AddTrack(XTrackInfo NewTrack)
    >>m_TrackInfo.emplace_back(NewTrack.GetTrackName() ,NewTrack.GetTrackLength());
    While yes, this looks right, this is slower and more verbose than it needs to be.
    This will call the constructor XTrackInfo(std::string TrackName, int Length) in XTrackInfo. But there are other constructors in the class. Which one do we usually call when we want to make a copy of something?
    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.

  8. #68
    Registered User
    Join Date
    Nov 2010
    Posts
    122
    Quote Originally Posted by Elysia View Post
    Consider the operations: "return a list of all tracks" and "print information of all tracks (for debugging purposes)". Both should suit what you need and it's up to you to implement one such function.
    I'll try to figure out how can I create an acessor function to the track collection.
    I'm not sure. But since the size of TrackInfo vector is unknown, I think that I'll need to use iterators.
    Learning OOP is tricky.


    Quote Originally Posted by Elysia View Post

    >>void AddTrack(XTrackInfo NewTrack)
    >>m_TrackInfo.emplace_back(NewTrack.GetTrackName() ,NewTrack.GetTrackLength());
    While yes, this looks right, this is slower and more verbose than it needs to be.
    This will call the constructor XTrackInfo(std::string TrackName, int Length) in XTrackInfo. But there are other constructors in the class. Which one do we usually call when we want to make a copy of something?
    Usually we use the default constructor. Can I do ?:
    Code:
    m_TrackInfo.emplace_back(NewTrack);
    Another thing. Is it correct access directly private variables? For the same reason that you have talked about on the previous post.

  9. #69
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by marcoesteves View Post
    I'll try to figure out how can I create an acessor function to the track collection.
    I'm not sure. But since the size of TrackInfo vector is unknown, I think that I'll need to use iterators.
    Learning OOP is tricky.
    Or you can, you know, create a function that prints the debug info you need without having to create an accessor function.
    The point is that I want you to ponder about how the interface of such a function--any type of function you would write to do this--would look like.

    Usually we use the default constructor. Can I do ?:
    Code:
    m_TrackInfo.emplace_back(NewTrack);
    No, it's called the copy constructor. But yes, you can do that.
    In C++11, it would be better to do
    m_TrackInfo.emplace_back(std::move(NewTrack));
    to utilize the move constructor, however. You will have to learn about rvalue references to properly understand this, though, but for now you can take my word for it.

    Another thing. Is it correct access directly private variables? For the same reason that you have talked about on the previous post.
    Depends on where you do it. Inside the class who owns the private variables? Yes.
    Outside the class (e.g. by creating member functions that directly returns these private member variables)? No. It destroys encapsulation and abstraction.
    Focus on building an interface that exposes "operations," i.e. what you want to do, not what variables you want to access.
    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.

  10. #70
    Registered User
    Join Date
    Nov 2010
    Posts
    122
    Quote Originally Posted by Elysia View Post
    Or you can, you know, create a function that prints the debug info you need without having to create an accessor function.
    The point is that I want you to ponder about how the interface of such a function--any type of function you would write to do this--would look like.

    Since we need print all of info stored at cds I think that is usefull create a function which access inside the vector of trackinfo.
    I don't know (yet) how to do it

  11. #71
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    If you want to user to be able to enumerate the tracks of a CD, you should first familiarize yourself with the iterator pattern.
    Then you should create appropriate begin() and end() functions, or at the very least cbegin() and cend().
    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.

  12. #72
    Registered User
    Join Date
    Nov 2010
    Posts
    122
    Quote Originally Posted by Elysia View Post
    If you want to user to be able to enumerate the tracks of a CD, you should first familiarize yourself with the iterator pattern.
    Then you should create appropriate begin() and end() functions, or at the very least cbegin() and cend().
    I was in vacations. I'm lost
    But I'll try catch up.
    I think that I need more theoretical background and/or doing/seeing more examples.

  13. #73
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Taking vector as an example:
    Code:
    std::vector<int> v = { 1, 2, 3 };
    for (auto it = v.begin(), end = v.end(); it != end; ++it)
    {
        if (it == v.begin())
            *it = 4;
        std::cout << *it << " ";
    }
    *(v.end() - 1) = 5;
    for (auto it = v.cbegin(), end = v.cend(); it != end; ++it)
        std::cout << *it << " ";
    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. #74
    Registered User
    Join Date
    Nov 2010
    Posts
    122
    I think it is time to look into "How to get trackinfo".

    I did an update to my code:

    Code:
    #include <iostream>
    #include <vector>
    #include <string>
    
    // You may not modify XTrackInfo
    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; }
        XTrackInfo GetTracks(Tracks) const{}
    
        int GetLength() const; // Left incomplete on purpose; you will implement it later
    
    
        void AddTrack(XTrackInfo NewTrack){
            //m_TrackInfo.emplace_back(NewTrack.GetTrackName(),NewTrack.GetTrackLength());
    
            m_TrackInfo.emplace_back(std::move(NewTrack));
    
        }
    
    
        // Add additional functions to this class as necessary to make it compile.
    };
    
    
    
    void PrintCdContents(const XMusicCd& Cd)
    {
        // Implement this function such that it compiles
        // Also, to be explicit, you may not add any tracks to the CD in here. That is not the purpose of this function. You may also not change the signature of the function.
        // You shall specifically not modify the CD object by calling any setters.
       //Cd.
    
        std::cout << "Author : " << Cd.GetAuthor() << "\n";
        std::cout << "\n" << std::endl;
        std::cout << "Track Info" << std::endl;
    
        for (auto it = NewTrack.begin(), end = NewTrack.end(); it != end; ++it)
        {
            std::cout << *it << " ";
        }
    
        // How can I acess the trackinfo vector inside of Cd class?
        //
    
    
    }
    
    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);
    }
    It doesn't work, why? I don't figure out how can I create an acessor to the Tracks vector which belongs to cd class.

    I think that I need to create a function getTracks which will return the Track contents. Probably the function type will be XTrackInfo type.

  15. #75
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Where is "NewTrack" defined?
    Where are the functions begin, end defined?
    Where are the operators ++ (prefix), != and * defined?
    What does the compiler say?

    You can create a function that returns all tracks or one track, if you will. You will get less encapsulation, though, and some programmers will come to expect to be able to iterate over tracks because... it's a standard pattern for all things that are iterable (all standard contains supports it).
    Last edited by Elysia; 09-01-2014 at 09:31 AM. Reason: Spell error
    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