Changing visibility of parent field?

Discussion in 'C++' started by carl, Feb 20, 2010.

  1. carl

    carl Guest

    I have a class which defines a private constructor and some private fields:

    private:
    NonRigidTransform(const Self&); //purposely not implemented
    void operator=(const Self&); //purposely not implemented

    /** The bulk transform. */
    BulkTransformPointer m_BulkTransform;

    /** Variables defining the coefficient grid extend. */
    RegionType m_GridRegion;
    SpacingType m_GridSpacing;
    DirectionType m_GridDirection;
    OriginType m_GridOrigin;

    DirectionType m_PointToIndex;
    DirectionType m_IndexToPoint;


    Now I made another class that extends the above class. But when I create the
    subclass I get some errors saying that the above fields are private. I have
    tried to change the above visibility to 'protected' and then it works. But
    since I would like to write my subclass without making changes in the
    baseclass I would like to know if its possible to change the visibility of
    the above fields in my subclass. Any ideas?
     
    carl, Feb 20, 2010
    #1
    1. Advertising

  2. On Feb 20, 9:59 pm, "carl" <carl@.com> wrote:

    > I have a class which defines a private constructor and some private fields:


    In C++ terminology, we use member rather than field.

    >
    > private:
    > NonRigidTransform(const Self&); //purposely not implemented
    >   void operator=(const Self&); //purposely not implemented


    What is Self? self is something like this pointer in Smalltalk or
    Simul languages.
    The correct declarations of copy constructor and copy assignment
    operator are:
    class NonRigidTransform {
    NonRigidTransform(const NonRigidTransform&);
    NonRigidTransform& operator=(const NonRigidTransform&);
    // ...
    };

    >
    >   /** The bulk transform. */
    >   BulkTransformPointer  m_BulkTransform;
    >
    >   /** Variables defining the coefficient grid extend. */
    >   RegionType    m_GridRegion;
    >   SpacingType   m_GridSpacing;
    >   DirectionType m_GridDirection;
    >   OriginType    m_GridOrigin;
    >
    >   DirectionType m_PointToIndex;
    >   DirectionType m_IndexToPoint;
    >
    > Now I made another class that extends the above class. But when I create the
    > subclass I get some errors saying that the above fields are private. I have
    > tried to change the above visibility to 'protected' and then it works. But
    > since I would like to write my subclass without making changes in the
    > baseclass I would like to know if its possible to change the visibility of
    > the above fields in my subclass. Any ideas?


    In C++, we use derived class rather than subclass.
    If you implement both base and derived class, then you have access to
    base class,
    so you can change the access control from private to protected.
    BTW, for constructing a derived class object you have
    to call base class constructor first.

    Good luck
    Regards,
    -- Saeed Amrollahi
     
    Saeed Amrollahi, Feb 20, 2010
    #2
    1. Advertising

  3. carl

    Robert Fendt Guest

    And thus spake "carl" <carl@.com>
    Sat, 20 Feb 2010 19:59:57 +0100:

    > Now I made another class that extends the above class. But when I create the
    > subclass I get some errors saying that the above fields are private. I have
    > tried to change the above visibility to 'protected' and then it works. But
    > since I would like to write my subclass without making changes in the
    > baseclass I would like to know if its possible to change the visibility of
    > the above fields in my subclass. Any ideas?


    The rather unusual coding style (read: unusual for C++)
    notwithstanding, the short answer to your question (as far as I
    understand it) is no. The very idea of marking a member
    "private" is that *no one* should be able to access it apart
    from the other class members and friends. It thus is considered
    "internal" to that class, period. You should know the concept,
    it is called 'encapsulation'.

    If a part of the class is supposed to be changed by derived
    classes then by definition it has to be marked as protected.
    Protected access means that the member is part of the interface
    the base class provides to derived classes. This is C++ 101, and
    there's no way around it rather than explicitely making all
    derived classes friends of the base (and I hope I do not have to
    tell you that this is a curious perversion of C++'s features
    rather than proper design).

    Regards,
    Robert
     
    Robert Fendt, Feb 21, 2010
    #3
  4. "Leigh Johnston" <leigh@.co.uk> writes:
    > "carl" <carl@.com> wrote in message
    > news:4b803130$0$282$...
    >> Now I made another class that extends the above class. But when I
    >> create the subclass I get some errors saying that the above fields
    >> are private. I have tried to change the above visibility to
    >> protected' and then it works. But since I would like to write my
    >> subclass without making changes in the baseclass I would like to
    >> know if its possible to change the visibility of the above fields in
    >> my subclass. Any ideas?

    >
    > You could use private inheritance and using declarations but it all
    > sounds a bit horrid. Member variables should typically be private so
    > you do not break invariants or protected if you know what you are
    > doing and the class is designed to be a base class.


    Leigh, I'm not sure exactly how you're proposing this would work here.
    Using declarations cannot make visible what is not already visible. And
    what is it that you suppose that private inheritance adds? Are you
    thinking that private inheritance somehow makes private members of the
    base class available to the derived class? I'm not sure from your
    wording, but then if not that then I don't see what it adds. Take this
    example:

    class A {
    private:
    int mA_private;
    protected:
    int mA_protected;
    public:
    int mA_public;
    };

    class B : private A {
    public:
    // using A::mA_private; // Not visible here ...
    using A::mA_protected;
    using A::mA_public;
    };

    int main()
    {
    B b;
    // b.mA_private = 0;
    b.mA_protected = 1;
    b.mA_public = 2;
    }

    Here, B can *extend* the scope of the members of A that are visible to
    it through using declarations, but it cannot make A's private members
    visible, not even to itself.

    Regards

    Paul Bibbings
     
    Paul Bibbings, Feb 22, 2010
    #4
  5. carl

    John H. Guest

    On Feb 20, 12:59 pm, "carl" <carl@.com> wrote:
    > I have a class which defines a private constructor and some private fields:


    With private members, no one can access it but the same class. Not
    even derived class. protected access gives derived class access.

    Private constructors mean that only that class can construct itself.
    When ever you have a base class, the child class will need to call the
    base class constructor. This is done in the child class constructor
    either explicitly by the programmer or implicitly by the compiler.

    class Parent
    {
    private:
    Private()
    {
    }
    };

    class Child : Parent
    {
    Parent(int i) :
    Private() // <--- explicit call to Private()
    {
    }
    Parent()
    { // <<-- here, the compiler needs to call Private(), even though
    you didn't tell it to
    }
    };

    Since Private() is private, neither of these constructors are allowed,
    and it cannot compile. Thus, the constructor must be protected (or
    public):

    class Parent
    {
    protected:
    Private()
    {
    }
    };

    Now the child class can access Private() and be able to constructor
    his parent class as needed.

    > Now I made another class that extends the above class. But when I create the
    > subclass I get some errors saying that the above fields are private. I have
    > tried to change the above visibility to 'protected' and then it works.
    > But
    > since I would like to write my subclass without making changes in the
    > baseclass I would like to know if its possible to change the visibility of
    > the above fields in my subclass.


    It sounds like you want to keep the members of the parent class
    private, but add protected "accessor" methods to those members:

    class Parent
    {
    protected:
    Private()
    {
    }
    int getMember1()
    {
    return member1;
    }
    private:
    int member1;
    };

    Now Child can see the value of member1 via the protected method
    getMember1(). However because getMember1() just returns a copy of the
    value of member1, it does not let outside classes change it. To
    further emphasize this "read-only"ness of the accessor method, you
    should make it a const member function:

    class Parent
    {
    protected:
    Private()
    {
    }
    int getMember1() const // <--- add const to member functions
    which do not modify the class
    {
    return member1;
    }
    private:
    int member1;
    };

    To summarize, now Parent can used as a parent class (and only a parent
    class), and only the parent class can change the values of its
    members. However the child class is free to use (read) the value of
    the parent class's member variables via the parent class's accessor
    methods.
     
    John H., Feb 22, 2010
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    1
    Views:
    644
    Eliyahu Goldin
    Jan 21, 2005
  2. ehm
    Replies:
    2
    Views:
    215
  3. Micky Pearce
    Replies:
    1
    Views:
    103
    Mick White
    May 25, 2004
  4. Sound
    Replies:
    2
    Views:
    476
    Randy Webb
    Sep 28, 2006
  5. jr
    Replies:
    3
    Views:
    469
Loading...

Share This Page