Online Book Reader

Home Category

Professional C__ - Marc Gregoire [129]

By Root 1306 0
calling the public tell() method of a Blabber object would effectively access the protected method of the Secret class. Of course, this doesn’t really change the access level of dontTell(), it just provides a public way of accessing it.

You could also override dontTell() explicitly in the Blabber subclass and give it new behavior with public access. This makes a lot more sense than reducing the level of access because it is entirely clear what happens with a reference or pointer to the base class. For example, suppose that Blabber actually made the dontTell() method public:

class Secret

{

protected:

virtual void dontTell() { cout << "I'll never tell." << endl; }

};

class Blabber : public Secret

{

public:

virtual void dontTell() { cout << "I'll tell all!" << endl; }

};

If the dontTell() method is called on a Blabber object, it will output I'll tell all!

myBlabber.dontTell(); // Outputs "I'll tell all!"

In this case, however, the protected method in the superclass stays protected because any attempts to call Secret’s dontTell() method through a pointer or reference will not compile.

Blabber myBlabber;

Secret& ref = myBlabber;

Secret* ptr = &myBlabber;

ref.dontTell(); // BUG! Attempt to access protected method.

ptr->dontTell(); // BUG! Attempt to access protected method.

The only truly useful way to change a method’s access level is by providing a less restrictive accessor to a protected method.

Copy Constructors and the Equals Operator in Subclasses

Chapter 7 says that providing a copy constructor and assignment operator is considered a good programming practice when you have dynamically allocated memory in the class. When defining a subclass, you need to be careful about copy constructors and operator=.

If your subclass does not have any special data (pointers, usually) that require a nondefault copy constructor or operator=, you don’t need to have one, regardless of whether or not the superclass has one. If your subclass omits the copy constructor or operator=, a default copy constructor or operator= will be provided for the data members specified in the subclass and the superclass copy constructor or operator= will be used for the data members specified in the superclass.

On the other hand, if you do specify a copy constructor in the subclass, you need to explicitly chain to the parent copy constructor, as shown in the following code. If you do not do this, the default constructor (not the copy constructor!) will be used for the parent portion of the object.

class Super

{

public:

Super();

Super(const Super& inSuper);

};

class Sub : public Super

{

public:

Sub();

Sub(const Sub& inSub);

};

Sub::Sub(const Sub& inSub) : Super(inSub)

{

}

Similarly, if the subclass overrides operator=, it is almost always necessary to call the parent’s version of operator= as well. The only case where you wouldn’t do this is if there is some bizarre reason why you only want part of the object assigned when an assignment takes place. The following code shows how to call the parent’s assignment operator from the subclass:

Sub& Sub::operator=(const Sub& inSub)

{

if (&inSub == this) {

return *this;

}

Super::operator=(inSub) // Calls parent's operator=.

// Do necessary assignments for subclass.

return *this;

}

If your subclass does not specify its own copy constructor or operator=, the parent functionality continues to work. If the subclass does provide its own copy constructor or operator=, it needs to explicitly reference the parent versions.

The Truth about virtual

When you first encountered method overriding earlier in this chapter, we told you that only virtual methods can be properly overridden. The reason we had to add the qualifier properly is that if a method is not virtual, you can still attempt to override it but it will be wrong in subtle ways.

Hiding Instead of Overriding

The following code shows a superclass and a subclass, each with a single method. The subclass is attempting to override the method in the superclass, but it is not declared to be virtual in the superclass.

Return Main Page Previous Page Next Page

®Online Book Reader