Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
613 views
in Technique[技术] by (71.8m points)

c++ - How can a derived class use a protected member of the base class?

Say that a base class A defines a protected member. A derived class B uses this member.

class A
{
public:
  A(int v) : value(v) { }

protected:
  int value;
};

class B : public A
{
public:
  B(int v) : A(v) { }
  void print() const;
  void compare_and_print(const A& other) const;
};

The function B::print just takes the value of the current member and prints it:

void B::print() const
{
  std::cout << "Value: " << value << "
";
}

The other member function, B::compare_and_print, takes an instance of A, checks their values and prints the maximum of both:

void B::compare_and_print(const A& other) const
{
  auto max_value = std::max(value, other.value);
  std::cout << "Max value: " << max_value << "
";
}

If other were an instance of the class B, this would be no problem. But the function would like to work with any kind of A instances. This does unfortunately not compile. This is what clang says about this:

test.cpp:27:42: error: 'value' is a protected member of 'A'
  auto max_value = std::max(value, other.value);
                                         ^
test.cpp:9:7: note: can only access this member on an object of type 'B'
  int value;
      ^
1 error generated.

This restriction sounds counter-intuitive to me. However, I'm not going to dispute the C++ standard about this (I'm nevertheless interested about the rationale behind this decision).

My problem is that in my project I really have this kind of use case: A derived class has a method that takes an instance of the base class and needs to access a protected member of the received object.

The easiest solution, the one I implemented currently, is to add a public member function to the base class, which returns the protected member. This solution does not fully satisfy me because I would like to avoid exporting the member this way.

How can I enable the usage of the base class' protected member by the derived class without exporting the member through the API?


EDIT: Some related questions are:

The answer I would like to have is the explanation of a design pattern to solve this problem without exposing the the protected member to the external code (where external means, code that is not part of the framework defining these classes).

It could be that such a pattern cannot exist, I acknowledge.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There is actually a loophole using member pointers (no casting, no copying):

void B::compare_and_print(const A& other) const
{
  auto max_value = std::max(value, other.*(&B::value));
  std::cout << "Max value: " << max_value << "
";
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...