Changing visibility of parent field?

C

carl

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?
 
S

Saeed Amrollahi

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
 
R

Robert Fendt

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
 
P

Paul Bibbings

Leigh Johnston said:
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
 
J

John H.

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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,049
Latest member
Allen00Reed

Latest Threads

Top