CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 20
  1. #1
    Join Date
    Jul 2014
    Posts
    3

    Red face C++ with OOP assignment

    Help Please this assignment is due by Sunday 7/20/2014

    We will use one source code file to learn how to program object abstractions (commonly referred to as object-oriented classes). We will see how encapsulation, object abstractions, and information hiding are distinct and very significant concepts in C/C++. This should clarify the misunderstandings that result from using object-oriented terms that are appropriate specifically for Object-Oriented Analysis, versus Object-Oriented Design, and Object-Oriented Implementation in C++ .

    Please, pay close attention to the threaded discussion posts as they provide key definitions necessary for successfully accomplishing the labs in both coming weeks.

    Lab for Week #2

    Concerning encapsulation:

    Best Definition for OO Design phase:

    Encapsulation is the packaging into a single unit highly related states and methods of an entity.

    Best definition for implementation phase:

    An encapsulation is a proscriptive boundary in the source code such that any interaction across the boundary is allowed by the compiler only if performed in accordance with a formally defined interface. (COMP220 class definition)

    The act of proscription is implemented by the compiler's refusal to emit code that access members inside the encapsulation. Instead, the compiler issues a diagnostic: “is private” or “it is not accessible”

    The formal interface is the class definition. A class definition always creates a collective type handle known as the name of an OO class. The C++ keywords used to define OO classes are class and struct. Because, classes may be nested,

    class1::class2::class3 is a perfectly valid collective type handle.

    WARNING: There are special rules for using handles with the same name but of different kind. For example, 1) the name of a constructor is also the name of the class, 2) an object (Object Handle) named identically to a class name (collective type handle) hides the class (never can be instantiated again) for the rest of the program. This is an excellent security feature of C++.

    Lab Procedure Week #2

    1) Download the source code file named EncapInherit.cpp.
    2) As appropriate prepare files required from your development environment.
    3) Compile the file and execute it.
    4) Study the source code
    5) Create a backup copy of the file EncapInherit.cpp.
    6) Using the operating system, find out the size of the executable file created by compiling the source code file EncapInherit.cpp.
    7) Change all member access specifiers from private or protected to public. Do not change the inheritance access specifiers.
    8) (If in an IDE clean the project) recompile and link the program.
    9) Repeat step 6 and describe any size changes.
    */
    #include "iostream"
    using namespace std;

    class WritingInstruments
    {
    protected:
    unsigned int RemainingWritingSubstance; // measured in # of chars
    public:
    explicit WritingInstruments // Do not allow for conversion purposes
    ( unsigned int AmountOfWritingSubstance = 5 )
    { RemainingWritingSubstance = AmountOfWritingSubstance; }
    bool Write( unsigned int NumberOfCharacters2Write )
    {
    bool Rtn = true;
    if( NumberOfCharacters2Write <= RemainingWritingSubstance )
    RemainingWritingSubstance -= NumberOfCharacters2Write;
    else
    {
    Rtn = false;
    RemainingWritingSubstance = 0;
    }
    return Rtn;
    }
    unsigned int LookAtIt() { return RemainingWritingSubstance; }

    };

    class Pens : public WritingInstruments
    {
    bool CapIsOn;

    public:

    explicit Pens(unsigned int Ink = 5, bool CapPassed = true) : WritingInstruments(Ink)
    { CapIsOn = CapPassed;

    }

    bool Write( unsigned int NumberOfCharacters2Write )
    {
    if(CapIsOn) return false;
    return WritingInstruments::Write( NumberOfCharacters2Write );
    // Notice that here we fail to distinguish a failure to write because
    // the cap is on from a failure to write because the pen ran out of ink
    // Clearly, despite our efforts this inheritance does not meet Liskov's
    // sustitution principle. It is possible to meet Liskov if all Pens
    // objects are created with the cap off.
    }

    void LookAtIt() // I violate the encapsulation here
    {
    cout << "The cap is " << (CapIsOn ? " on " : " off ") << endl;
    cout << "and there is enough ink left to write "
    << RemainingWritingSubstance << " characters" << endl;
    }
    void CapOn(){ CapIsOn = true; }
    void CapOff(){ CapIsOn = false; }
    };

    class Pencils : public WritingInstruments
    {
    unsigned int RemainingB4Sharpening; // zero means cannot write
    public:
    const unsigned int CharactersPerSharpenning;

    explicit Pencils(unsigned int Lead = 5U, bool TipIsSharp = false,
    unsigned int ChPerSharp = 3U)
    : WritingInstruments(Lead), CharactersPerSharpenning(ChPerSharp)
    {
    RemainingB4Sharpening = 0U;
    }

    bool Write( unsigned int NumberOfCharacters2Write )
    {
    while (
    RemainingB4Sharpening-- &&
    RemainingWritingSubstance-- &&
    NumberOfCharacters2Write--
    );

    return !NumberOfCharacters2Write;
    }

    void Sharpen() { RemainingB4Sharpening = CharactersPerSharpenning; }
    };

    //------------------------- MAIN ------------------------------



    int main()
    {
    WritingInstruments MyPen(8), YourPen;
    // Pens MyPen(8), YourPen;

    // MyPen.CapOff(); // Open my pen for writing

    for( int i = 1; i <= 5; i++)
    {

    cout << "\n---------writing for the " << i << "th time ---------\n";

    cout << "MyPen: ";
    MyPen.LookAtIt();
    cout << "\nYourPen: ";
    YourPen.LookAtIt();
    cout << endl;

    if( MyPen.Write(2) )
    cout << "\nMy pen successfully wrote 2 more charactrers" << endl;
    else cout << "\nMy pen ran out of ink " << endl;

    if( YourPen.Write(2) )
    cout << "Your pen successfully wrote 2 more charactrers" << endl;
    else cout << "Your pen ran out of ink " << endl;
    }

    system("pause");
    return 0;
    }

  2. #2
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    Re: C++ with OOP assignment

    When posting code, please use code tags. Go advanced, select the code and click '#'.

    Help Please this assignment is due by Sunday 7/20/2014
    You shouldn't leave it so late. You don't say what help you need. As this is an assignment, we won't do the work for you. See http://forums.codeguru.com/showthrea...ork-assignment

    If you ask specific questions we'll be able to provide guidance short of actually doing the work.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  3. #3
    Join Date
    Jul 2014
    Posts
    3

    Re: C++ with OOP assignment

    Change all member access specifiers from private or protected to public. Do not change the inheritance access specifiers.

  4. #4
    Join Date
    Jul 2014
    Posts
    3

    Re: C++ with OOP assignment

    7) Change all member access specifiers from private or protected to public. Do not change the inheritance access specifiers.

  5. #5
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    Re: C++ with OOP assignment

    Quote Originally Posted by austinsalankey View Post
    7) Change all member access specifiers from private or protected to public. Do not change the inheritance access specifiers.
    Yes, but that is what you are required to do as part of the assignment. So why don't you just do it if this is what you are required to do.

    So I'll ask again - what exactly is your specific c++ question?
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  6. #6
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    Re: C++ with OOP assignment

    Is there actually any point to this 'lab procedure'?
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  7. #7
    Join Date
    Jul 2013
    Posts
    576

    Re: C++ with OOP assignment

    Quote Originally Posted by austinsalankey View Post
    7) Change all member access specifiers from private or protected to public. Do not change the inheritance access specifiers.
    In this line,

    class Pens : public WritingInstruments

    public is the inheritance access specifier. You should not change that.

    You should change the member access specifiers though to public. The easiest way to do that is to put in

    public:

    at the very beginning of each class definition and then comment out all occurances of protected: and private:

    Then check if this change leads to a change in the size of the compiled EncapInherit.cpp file.

    ---

    It's hard to see any purpose of this really. I mean the size of a compilation unit is hardly something that should influence the choise of access specifiers. So it's probably just a way to enforce a minimal amount of hands-on lab work on your part in preparation for more to come. I should hope so because the theoretical level of this lab is very high and there's a huge discrepancy between that and the task you were required to perform so far.
    Last edited by razzle; July 20th, 2014 at 03:56 AM.

  8. #8
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: C++ with OOP assignment

    Quote Originally Posted by austinsalankey
    2) an object (Object Handle) named identically to a class name (collective type handle) hides the class (never can be instantiated again) for the rest of the program. This is an excellent security feature of C++.
    Err... your teacher is mistaken:
    Code:
    // Define a class named X and also define an object of this class that is also named X:
    class X
    {
        int n;
    } X;
    
    int main()
    {
        // Define another object of class X named x1:
        class X x1;
    }
    Admittedly, we normally would use X as the class name instead of class X, but this demonstrates that this name hiding is not "an excellent security feature of C++".

    Quote Originally Posted by razzle
    I mean the size of a compilation unit is hardly something that should influence the choise of access specifiers.
    Maybe the aim is to demonstrate to the student that there is no change in size? Personally, I have never bothered to take note.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  9. #9
    Join Date
    Jul 2013
    Posts
    576

    Re: C++ with OOP assignment

    Quote Originally Posted by laserlight View Post
    Admittedly, we normally would use X as the class name instead of class X, but this demonstrates that this name hiding is not "an excellent security feature of C++".
    I wasn't aware of this way of creating rudimentary Singletons but it seems to protect quite well against multiple instantiation by accident. And Stroustrup has stated that protection against accidental misuse is the highest level of protection C++ offers; C++ is too low-level to withstand tampering by a determined programmer; That's the price we pay for C++ as a systems programming language.

    But even so I don't consider this an excellent feature that should be promoted. The reason is that Singletons are generally malign and should be avoided also in this form. Especially by unexperienced programmers still in education.

  10. #10
    Join Date
    Jul 2013
    Posts
    576

    Re: C++ with OOP assignment

    Quote Originally Posted by austinsalankey View Post
    Concerning encapsulation:

    Best Definition for OO Design phase:

    Encapsulation is the packaging into a single unit highly related states and methods of an entity.

    Best definition for implementation phase:

    An encapsulation is a proscriptive boundary in the source code such that any interaction across the boundary is allowed by the compiler only if performed in accordance with a formally defined interface. (COMP220 class definition)

    The act of proscription is implemented by the compiler's refusal to emit code that access members inside the encapsulation.
    Finally a newbie C++ course with a high OO content! It certainly beats the traditional endless toiling over copy constructors and copy assignment operators that scare budding programmers off to Java and C# in droves.

    Still I get a little suspicious when something is presented categorically as the ultimate best. I don't know who produced the definitions above but I think they confuse the concepts of encapsulation and information hiding. To me "packaging into a single unit" is an example of encapsulation whereas upholding "a proscriptive boundary" is information hiding.

    Encapsulation (or whatever concept you define) must mean the same both in design and implementation. You cannot have a double standard. And not only that. Design and implementation feed from each other so ideally they are allowed to evolve in parallel. (As you may have guessed I'm quite fond of the Agile movement ),

    http://agilemanifesto.org/principles.html

    Furthermore I think it's time to drop all these old and tired OO definitions and concepts and concentrate on the type system itself. Any language that allows its type system to be extended by the programmer is an OO language. And OO programming simply is the process of producing new types using primitive types such as ints and doubles and existing types made by yourself and others most notably the standard library.

    Cheers and happy summer !!!
    Last edited by razzle; July 21st, 2014 at 10:17 AM.

  11. #11
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: C++ with OOP assignment

    Quote Originally Posted by razzle
    I wasn't aware of this way of creating rudimentary Singletons but it seems to protect quite well against multiple instantiation by accident.
    Possibly. It would also be necessary to disable copying to avoid problems with say, function templates and maybe the C++11 use of auto, but that is bog standard for implementations of the singleton pattern anyway.

    Quote Originally Posted by razzle
    And Stroustrup has stated that protection against accidental misuse is the highest level of protection C++ offers; C++ is too low-level to withstand tampering by a determined programmer; That's the price we pay for C++ as a systems programming language.
    The truth is that all programmng languages are held to that same standard. Language designers can try to anticipate ways by which programmers who are up to no good can subvert this or that, but ultimately loopholes and concessions will be made. It is not just about C++ beng a systems programming language. Nonetheless, my example shows that the teacher is mistaken about this method being "an excellent security feature of C++".

    Quote Originally Posted by razzle
    But even so I don't consider this an excellent feature that should be promoted. The reason is that Singletons are generally malign and should be avoided also in this form. Especially by unexperienced programmers still in education.
    Agreed, though my reasoning has to do with global state rather than singletons per se.

    Quote Originally Posted by razzle
    I don't know who produced the definitions presented here but I think they confuse the concepts of encapsulation and information hiding. To me "packaging into a single unit" is an example of encapsulation whereas upholding "a proscriptive boundary" is information hiding.

    Also encapsulation (or whatever concept you define) must mean the same both in design and implementation. You cannot have a double standard.
    Yeah, I have never heard of the concepts differing for design versus implementation. The implementation should express the design.

    Quote Originally Posted by razzle
    Furthermore I think it's time to drop these old tired OO definitions and concepts and concentrate on the type system itself. Any language that allows its type system to be extended by the programmer is an OO language. And OO programming simply is the process of producing new types using primitive types such as ints and doubles and existing types made by yourself and others.
    That simplification would be missing the polymorphic element of what it means to be "object oriented", but it would probably be sufficient to just mention "and has support for Liskov substitution". I am not sure if the simplification covers prototype based OOP, but I think the answer is yes by reasoning that every object has an inherent type due to its members, thus adding or removing members from a prototype would mean that the derived object has extended the type system.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  12. #12
    Join Date
    Jul 2013
    Posts
    576

    Re: C++ with OOP assignment

    Quote Originally Posted by laserlight View Post
    Nonetheless, my example shows that the teacher is mistaken about this method being "an excellent security feature of C++".
    I agree. Still I would like to give the teacher one point for the implementation idea. But then I immediately withdraw it again for the dire design implications. Singletons shouldn't be promoted so the teacher ends up with naught.

    That simplification would be missing the polymorphic element of what it means to be "object oriented", but it would probably be sufficient to just mention "and has support for Liskov substitution". I am not sure if the simplification covers prototype based OOP, but I think the answer is yes by reasoning that every object has an inherent type due to its members, thus adding or removing members from a prototype would mean that the derived object has extended the type system.
    Well all major modern languages support all four common kinds of polymorphisms so it's not like subtype polymorphism is missing from type systems.

    Although OO traditionally only deals with subtype polymorphism many languages today support combinations of subtype and parametric polymorphisms. It indicates that subtype polymorphism isn't such a cut in stone defining feature of OO after all. And look at the celebrated Liskov principle you mention. It's not a defining feature of OO really, but has been adopted by the OO community as a qualitative principle of what constitutes good OO. And most notably it's defined in terms of types!

    So in my view the notion of an "extension of the type system" is a much cleaner and simpler concept than the traditional view(s) of OO. You don't end up with quirky and contradicting definitions like for example in this lab where teachers make a big deal out of clarifying disparate definitions of OO and then still get it wrong. Also "extending the type system" makes it perfectly clear what OO is all about and exactly how this approach differs from the procedural paradigm. Finally it puts away the rather naff controversy over OO vs. generic programming. Just mix and match subtype and parametric polymorphisms to your heart's desire. It's not either or, it's both.
    Last edited by razzle; July 23rd, 2014 at 02:21 AM.

  13. #13
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: C++ with OOP assignment

    Quote Originally Posted by razzle View Post
    The reason is that Singletons are generally malign and should be avoided also in this form.
    There's nothing malign about singletons per se, when used incorrectly, yes, but the same is true for any construct used incorrectly. Sometimes they're exactly the thing that's needed for the problem at hand.

    The problem starts really when developers see an object that should only have one instance and then wrap it in a singleton construct. Is this wrong? no. Is it right? maybe, maybe not.
    A note in the documentation could be enough.
    A simple debug-mode assert (increasing a debug-only static count member) could be enough.
    A formal wrapping in a singletone object really is only a necessity when there are multiple places where object construction/destruction can occur and the code flow as to which path gets there isn't well defined.

    While the solution in #8 'works', it has disadvantages of it's own. Object construction is at program start, and ends at program end. If this is located in a .dll, then construction happens inside the dllmain() which could be catastrophic depending on what construction/destruction does because there are severe restrictions on what you can safely do inside dllmain. "hiding" the class name in this manner also has some issues when trying to access static members of the class (which isn't uncommon to find in singletons).
    I would never recommend this as a means to an end, it's more of a quirk of the language resulting from it's C heritage that you can even do this than an actual intended purpose. (and unfortunately C++ has a lot of these quirks).
    The solution (obviously) also has issues if this is located in a header and the header is included in many sources. Generally speaking, "it's a bad idea".


    Quote Originally Posted by laserlight View Post
    Quote Originally Posted by razzle View Post
    I mean the size of a compilation unit is hardly something that should influence the choise of access specifiers.
    Maybe the aim is to demonstrate to the student that there is no change in size? Personally, I have never bothered to take note.
    it's just downright wrong to try to infer anything from the size of the exe. At best it can give you a rough indication that "something is wrong" when parts of code suddenly get inlined (or not) or that an extra lib gets dragged in (this could be critical for embedded projects with limited memory).

    Changing the access specifiers shouldn't impact code size. Though in a few rare conditions it could if you drag in SFINAE and alternate code being compiled because of that. But changing access specifiers will change the name mangling which could end up impacting the import/export tables, which in return may influence the size of the exe/dll. And even if it did have an influence (or not) on the exe size with one compiler/linker, there's no guarantee the same kind of result will be true for every compiler/linker suite.

    In any case, access specifiers serve a purpose that has nothing to do with code/binary size, and any inference made this way is pointless. You pick the specifier because you want some things accessible and some things not (or only by derived classes). There really is no point or truth in this particular exercise.

  14. #14
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: C++ with OOP assignment

    Quote Originally Posted by OReubens
    "hiding" the class name in this manner also has some issues when trying to access static members of the class (which isn't uncommon to find in singletons).
    You can access them from the object itself, so I do not see an issue for static members. Besides, I thought that the main reason why they are common for singleton implementations is that the function to get the instance is invariably a static member function, but that of course would not apply here.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  15. #15
    Join Date
    Jul 2013
    Posts
    576

    Re: C++ with OOP assignment

    Quote Originally Posted by OReubens View Post
    There's nothing malign about singletons per se,
    That's right in the moral sense. Singletons cannot be malign because they lack a conscience. The same goes for guns. They're not inherently malign but may become so in the hands of a shooter. And guns undisputedly have great capacity for damage.

    The same is true for some programming mechanisms most notably Singletons (global data) and gotos (unstructured jumps). They are the smoking guns of programming and better be avoided. (note I didn't say banned because they do have legitimate uses).

    http://c2.com/cgi/wiki?GlobalVariablesAreBad
    http://c2.com/cgi/wiki?GotoConsideredHarmful

    it's just downright wrong to try to infer anything from the size of the exe.
    It was probably just a control question to ensure students familiarise themselves with the lab environment.
    Last edited by razzle; July 24th, 2014 at 03:37 AM.

Page 1 of 2 12 LastLast

Posting Permissions

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





Click Here to Expand Forum to Full Width

Featured