Hello, everyone. I have a question to ask. According to The C++ Programming Language (3rd. Ed.) by Bjarne Stroustrup on page 405: "Members declared protectedare far more open to abuse than members declared private . In particular, declaring data members protected is usually a design error. Placing significant amounts of data in a common class for all derived classes to use leaves that data open to corruption. Worse, protected data, like public data, cannot easily be restructured because there is no good way of finding every use. Thus, protected data becomes a software maintenance problem."

Now I have a class for which I think a protected member is needed, it is an Image class that relys on a Bitmap data structure(declared as protected), and an ImageSection class(used to represent a part of an Image) inheriting from Image which also relys on the Bitmap data structure and some other attributes. So I am wondering whether this is a design error, if so, how to design these two classes?

Yap, I can do that, but it seems kinda awkward that the Image class can use the Bitmap structure directly while the ImageSection class can not.

I just have no idea why Bjarne Stroustrup states that "In particular, declaring data members protected is usually a design error.".
Then what is the best solution to this kind of design problem?

I just have no idea why Bjarne Stroustrup states that "In particular, declaring data members protected is usually a design error.".

I think you do - he tells you his exact reasons in the extract you quoted.
You could have a number of derived classes in your application which use protected members in the base class. If you're working on a derived class it's easy to navigate to the base class and examine the members, but if you're working on the base class and modify a member you are going to have to search the application for all derived classes which use that member, and possibly modify them too. It's just a global variable kind of problem on a smaller scale.
Remember, these issues aren't always black and white. Stroustrup does say "...declaring data members protected is usually a design error", and "Placing significant amounts of data in a common class...", so you must weigh up the additional maintenance against a possibly less obvious alternative design in your own case. In a small app with few derived classes and little common data the maintenance can be acceptable. For larger apps you might consider phoenix911's solution, or provide the derived class with it's own copy of the data.
I've seen it done both ways, and both can be correct in my view. Just be aware of the issue and you can defend the choice you make for your application.

Comments
Good

Making variables non-private is only an issue for public APIs.

Assume ALL API specifications to be public, period.

Protected (and even public) data members have their place, but that place is mostly to be found in performance critical situations where the extra overhead of creating call stacks for the getters and setters to these data members would be prohibitive.
Examples might be small classes that are uses extensively in an application, like a 3D Vector or 4D Matrix in a ray tracer.
For those (where the data members are accessed at a very high rate in comparison to most other operations) the use of getters and setters rather than direct access to the data members would yield an unacceptable performance overhead.

For most business applications however that's usually not a problem as they spend the vast majority of their time either waiting for user input, external events, or external data.

Another place might be classes that are completely internal to your library, like pure abstract classes.
For those there is no way they would ever be used directly, the only use is by derived classes. Giving those protected data members yields the same result as providing those data members as private in every inheriting class without the overhead of actually manually adding those members to each of those classes.

Another place might be classes that are completely internal to your library, like pure abstract classes.

So you're repeating what I just said.

So you're repeating what I just said.

no, I'm specifying and expanding on it, not repeating it.

This question has already been answered. Start a new discussion instead.