Thread: how to prevent encapsulation in c++ ?

  1. #1
    Registered User
    Join Date
    Jan 2014
    Posts
    6

    how to prevent encapsulation in c++ ?

    using pointers this program is violating encapsulation rule-

    Code:
    class MyClass
    {
        int i;
    public:
        int j;
        MyClass(int temp1,int temp2){i=temp1;j=temp2;}
    }ob1(5,6);
    
    void main()
    {
        int *ptr = &ob1.j;
        cout<<"j="<<*ptr;
        ptr--;
        cout<<"i="<<*ptr;
        getchar();
    }
    Now my question is ,is there any solution to this violation of encapsulation ?

  2. #2
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Now my question is ,is there any solution to this violation of encapsulation ?
    O_o

    There is no such violation; you've specifically told the client, also compiler, that the member `j' is `public'.

    Soma
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  3. #3
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,787
    Actually there is a violation, but that's because you're relying on the memory layout when you do ptr--, so *shrug*. It's not that different to indexing an array out of bounds.

  4. #4
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Actually there is a violation, but that's because you're relying on the memory layout when you do ptr--, so *shrug*.
    O_o

    [Edit]
    I now realize how argumentative this comes off, but the point remains, exposing any public data in a class forces the class to treat that exposed data and all related data as suspect. In any real class, the relation or interrelation of data to mechanic is the entire purpose of objects. Without being able to treat the data as conforming to expectation, as required of exposed data, the mechanic shouldn't be a class as you lose the benefit of writing code against such expectation.
    [/Edit]

    No. Arguing that the member `j' is encapsulated is silly as the member is specifically exposed; with that in mind, arguing that the class itself is somehow encapsulated is silly. In a real class, the one public member invariably exposes faults in precondition/postcondition assumptions. The only legitimate methodology available for using the data referenced by the class within the class is one of extreme distrust. Simply put, some of the object representation is expressly marked `public' which negates the expectation of encapsulation within the implementation.

    *shrug*

    I guess you could argue that violation happens with `public'; I'll certainly agree with that, but I don't think the original poster was looking for that.

    Admittedly, my own terse advice will be no easier for them to swallow.

    You are referring to cases with something more flaky:

    Code:
    class MyClass
    {
        int i;
        int j;
    public:
        MyClass(int temp1,int temp2){i=temp1;j=temp2;}
    }ob1(5,6);
     
    void main()
    {
        int *ptr = (int *)&ob1;
        *ptr = 0;
        cout<<"i="<<*ptr;
    }
    The class intentionally exposes no data beyond an interface implicitly trusting the contract; this is a violation of encapsulation by relying on memory layout.

    [Edit]
    For anyone who doesn't know: you can't protect against this sort of aliasing/coercion, and you should not try to protect against this sort of flaky code. If people violate the class contract you implement, it is only their fault when they "blow their entire leg off".
    [/Edit]

    Soma
    Last edited by phantomotap; 01-25-2014 at 03:29 AM.
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  5. #5
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,787
    Quote Originally Posted by phantomotap View Post
    O_o

    No. Arguing that the member `j' is encapsulated is silly as the member is specifically exposed;
    I'm arguing that 'i' should not be accessible and it's 'i' that the OP is accessing in the code in the original post (line 14), because ptr after decrementing is now point to a private object (i). I understand what you mean by trust but I do think the OP was referring to this access of 'i' (not 'j').

    Edit
    Of course you could simply recast the class to another class and do anything you like, so I agree with you there


    Edit 2:

    Quote Originally Posted by phantomotap

    For anyone who doesn't know: you can't protect against this sort of aliasing/coercion, and you should not try to protect against this sort of flaky code. If people violate the class contract you implement, it is only their fault when they "blow their entire leg off".
    Yes, I think this is the answer the OP might have been after
    Last edited by Hodor; 01-25-2014 at 03:34 AM.

  6. #6
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    I'm arguing that 'i' should not be accessible and it's 'i' that the OP is accessing in the code in the original post (line 14), because ptr after decrementing is now point to a private object (i)
    O_o

    Yes. You are arguing exactly that, but I'm arguing that the access to `i' is irrelevant as the data referenced by the class can't be trusted as encapsulated in any event because of the intentional exposure of data.

    Let me put it this way: you can't encapsulate member variables; the "owning" class is what must be encapsulated.

    In this example, the class isn't encapsulated regardless of what `main' implements.

    Code:
    class MyClass
    {
        int i;
    public:
        int j;
        MyClass(int temp1,int temp2){i=temp1;j=temp2;}
    }ob1(5,6);
     
    void main()
    {
        int *ptr = &ob1.j;
        cout<<"j="<<*ptr;
        *ptr = 0;
        getchar();
    }
    This code does not access `i' in any way, but the example is in every way as broken (That is, broken with respect to encapsulation.) as the original code.

    Soma
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  7. #7
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,787
    We're probably talking about the same thing but from different angles. I mean you can do this if you like skating on thin ice or completely crazy (not tested but it should work without crashing):

    Code:
    #include <iostream>
    
    class MyClass
    {
        int i;
    public:
        int j;
        MyClass(int temp1,int temp2){i=temp1;j=temp2;}
    }ob1(5,6);
      
    int main()
    {
        int *ptr = (int *)&ob1;
        for (size_t i = 0; i < sizeof (MyClass); i++)
            cout<<"blah="<<*ptr++<<" ";
     
        return 0;
    }
    Edit: perhaps that int *ptr should be an unsigned char *
    Last edited by Hodor; 01-25-2014 at 03:46 AM.

  8. #8
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    Out of curiosity, why would I ever want private elements of a struct? I get having constructors and function pointers is awesome but why would I ever want to hide it? Sorry if this comes off as inexperienced but I've never done anything in C++ like this before.

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by MutantJohn
    Out of curiosity, why would I ever want private elements of a struct? I get having constructors and function pointers is awesome but why would I ever want to hide it?
    To establish that these members are implementation detail. Hence, you can rename them, remove them or change their type without worrying that any code that uses the class will break.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Registered User
    Join Date
    May 2003
    Posts
    1,619
    Is there a solution? No. Regardless of whether or not you expose any of the private members of your class, there would always be some way to work around this with pointers. Encapsulation isn't a security feature, it's a feature designed to help enable good coding practices and help create the separation of interface and implementation. If you violate good practice and get creative enough you could easily get past that. That doesn't mean you should, but you always could.

    If you truly needed security (where outside code under any circumstances should not be able to access or change the data except through the provided interface), you can't permit the source data to live inside the same process's memory space.
    You ever try a pink golf ball, Wally? Why, the wind shear on a pink ball alone can take the head clean off a 90 pound midget at 300 yards.

  11. #11
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Out of curiosity, why would I ever want private elements of a struct? I get having constructors and function pointers is awesome but why would I ever want to hide it? Sorry if this comes off as inexperienced but I've never done anything in C++ like this before.
    O_o

    Consider:

    Code:
    class SMatrix
    {
        // ...
        f32 m[4][4];
    };
    So, you have a "4x4" class representing matrices, and you need to use that class so "..." represents a lot of good mechanics.

    Unfortunately, you can't, shouldn't try to, provide for every mechanic, but you eventually find you need to implement some mathematics for a client your interface doesn't support.

    Code:
    void DoSomething
    (
        SMatrix & f
    )
    {
        // ...
        f.m[1][1] = 0;
        // ...
    }
    Everything in the universe is grand.

    Except that the core routines are consuming most of the available compute--profiling--so you can legitimately to try and improve the implementation.

    Code:
    class SMatrix
    {
        // ...
         __m128 m[4];
    };
    You take the time to rewrite the core methods supporting "SSE" or similar instruction set.

    Now you have a problem: none of the client code, `DoSomething', works with the new version because a `__m128' is not a `f32[4][4]'. You could solve that with operator overloading by means of a second class overloading `operator []'.

    Code:
    class SVector
    {
        // ...
        __m128 m;
    };
    
    class SMatrix
    {
        // ...
        SVector m[4];
    };
    Now everything again works, but you become aware of an instruction set and algorithm which improves many operations by interleaving the data, and in implementing that, you are back at square one: the client code doesn't work.

    Code:
    class SMatrix
    {
        // ...
        void getAll(f32 *);
        void getColumn(size_t, f32 *);
        void getElement(size_t, size_t, f32 *);
        void getRow(size_t, f32 *);
        // ...
        void setAll(f32 *);
        void setColumn(size_t, f32 *);
        void setElement(size_t, size_t, f32 *);
        void setRow(size_t, f32 *);
        // ...
        __m128 m[4];
    };
    
    void DoSomething
    (
        SMatrix & f
    )
    {
        // ...
        f.setElement(1, 1, 0);
        // ...
    }
    This code works everywhere, and it would work everywhere regardless of `m' being `public', but by marking `m' as `public' you tell client code not to use `m' in the first place allowing you to make changes like these without potentially causing conflict in client code.

    Soma
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  12. #12
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by mannu1200 View Post
    Now my question is ,is there any solution to this violation of encapsulation ?
    That depends on what you consider a "solution" would achieve.

    By dereferencing ptr after decrementing it, your code is exhibiting undefined behaviour. It is certainly not guaranteed that it print obj1.i. With another compiler, your code could just as easily print something other than obj1.i. It could also reformat your hard drive (although, admittedly, interpreting a random area of memory as an int and printing it out rarely does more than print unexpected values).

    If j is made private, your code would not even compile. Code that does not compile cannot violate anything (except sensibilities of programmers who think it should compile).

    It is possible to use some idioms (e.g. pimpl) to ensure that i is stored elsewhere in memory, and not within an instance of MyClass.

    In the end, however, YOU are responsible for designing a class and ensuring it doesn't expose any more data than it needs to.

    That said, if a user of your class is determined enough, they will be able to bypass any mechanisms you put in place to protect your class' data. Access control (public, private, etc) and other language features are designed to prevent accidental problems in code due to coding errors. It is not designed to prevent a programmer from deliberately bypassing checks of the compiler, such ass your code does.



    Oh: main() returns int, not void.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Confused with encapsulation
    By Jefff in forum C++ Programming
    Replies: 6
    Last Post: 06-13-2012, 08:23 AM
  2. Encapsulation Vs Abstraction
    By Rakesh Kp in forum C++ Programming
    Replies: 1
    Last Post: 09-13-2011, 02:30 AM
  3. Encapsulation in C++
    By JohnLeeroy in forum C++ Programming
    Replies: 4
    Last Post: 05-08-2011, 05:02 PM
  4. encapsulation in c
    By swaugh in forum C Programming
    Replies: 2
    Last Post: 12-01-2004, 01:37 PM
  5. Integration or Encapsulation :: MFC
    By kuphryn in forum Windows Programming
    Replies: 0
    Last Post: 06-02-2002, 09:14 AM

Tags for this Thread