2

Fixed: modified as such:

3rd code piece, 1st line:    
static void writeFile(User &user)

User class:

User class:
void print() made public

Now it works as intended. Thanks to everyone that helped.

This is the original post:

1. class User {
2. protected:
3.      string name;
4.      string surname;
5.  .
6.  .
7.  .
8.      void print() {
9.          cout << name << " " <<surname; //etc
10.     }
11. }

Inherited class:

1. class DiscountUser : public User {
2. public:
3.      void print() {
4.          cout << "Discount ";
5.          User::print();
6.      }
7. }

And later in another class I have:

1. void writeFile(User user) {
2.     user.print();
3. }

And in another one:

1.  User *user = NULL;
2.
3.  if (userType == "Discount") {
4.      user = new DiscountUser(name, surname, code);
5.  }
6.  else {
7.      user = new BonusUser(name, surname, code);
8.  }
9.  writeFile(*user);

I get an error C2248: 'User::print' : cannot access protected member declared in class 'User'.

I know I get it because it's trying to access print() in the parent class. Is it because of the first line of the third code piece or did I really mess up with the pointers in the fourth one? Or because I'm a total loser and I'm missing something obvious?

6
  • my c++ is a bit rusty, but since User.print is protected, I would expect the User.print to be accessible from the DiscountUser class but not from "another class", which is one of the places where you're calling it from Commented Jun 1, 2015 at 22:15
  • for the sake of experimentation, what happens when you change void writeFile(User user) { to void writeFile(DiscountUser user) { Commented Jun 1, 2015 at 22:16
  • Since you went into the trouble of adding line numbers, why don't you tell us precisely on which line you get that error message? Commented Jun 1, 2015 at 22:19
  • @MikeNakis 3rd code piece, 2nd line. Commented Jun 1, 2015 at 22:22
  • @SamIam If i change it to DiscountUser user it works fine. But the thing is I want to access it from BonusUser as well. I know I'm missing something pretty basic. Commented Jun 1, 2015 at 22:23

3 Answers 3

3

The compiler knows which access rules apply by looking at the type of the pointer. Because the pointer is a User *, and print is protected in that class, it won't let you access it.

As a general rule you should keep the access level the same between the base and derived classes.

In addition to the compile error, you also have an error because writeFile is taking the object by value instead of by reference. When the parameter is copied for the function call, you'll get "slicing" where the type of the object is converted back down to the base class.

Sign up to request clarification or add additional context in comments.

2 Comments

I told you two things: first make print a public function in User, second change the parameter to writeFile from User to const User &.
I tried it, and i also modified Class::print to virtual void print() const however it still doesn't work as intended although I got rid of the compiler errors
1

Aside from the issues discussed in the other answers, you haven't used the virtual keyword on User::print. That means that even if everything were public, calls to it from a User* variable would always call the base method, even if the variable contains a derived object.

Looking back at the original question, I wonder if perhaps what you mean to do is have a public pure virtual print method in User and a protected non-virtual printImpl method that gets called from DiscountUser::print.

2 Comments

Virtual keyword "fixed" the error. I will never want call User::print. Only DiscountUser::print, and whatever::print
In that case, my suggestion of a pure virtual User::print is probably what you want.
1

In C++, access is determined by a variable's static type, not dynamic. Since writeFile's parameter's static type is User, print is protected, now matter what the dynamic type of user may happen to be.

Also, you should definitely pass User objects by reference (or pointer), not value. Otherwise you get what is known as "slicing" where only the base part of an object is copied, and that will really give you headaches.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.