与继承函数混淆

Confused with inherited functions

修正:修改为:

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

用户class:

User class:
void print() made public

现在它按预期工作了。感谢所有帮助过的人。

这是原文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. }

继承class:

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

稍后在另一个 class 我有:

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

在另一个中:

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);

我收到错误 C2248:'User::print':无法访问在 class 'User'.

中声明的受保护成员

我知道我明白了,因为它试图访问父 class 中的 print()。是因为第三个代码段的第一行还是我真的搞砸了第四个代码段中的指针?或者因为我是一个彻头彻尾的失败者,我错过了一些明显的东西?

编译器通过查看指针的类型知道适用哪些访问规则。因为指针是 User *,并且 print 在 class 中受到保护,所以不会让您访问它。

作为一般规则,您应该在基础和派生 classes 之间保持相同的访问级别。

除了编译错误之外,您还有一个错误,因为 writeFile 按值而不是按引用获取对象。当为函数调用复制参数时,您将得到 "slicing",其中对象的类型被转换回基础 class。

在 C++ 中,访问是由变量的静态类型决定的,而不是动态的。由于writeFile的参数的静态类型是Userprintprotected,现在不管user的动态类型是什么。

此外,您绝对应该通过引用(或指针)而不是值来传递 User 对象。否则你会得到所谓的 "slicing",其中只复制对象的基础部分,这真的会让你头疼。

除了其他答案中讨论的问题外,您还没有在 User::print 上使用 virtual 关键字。这意味着即使一切都是 public,从 User* 变量调用它也将始终调用基方法,即使该变量包含派生对象。

回顾最初的问题,我想知道你的意思是不是在 User 中有一个 public 纯虚拟 print 方法和一个受保护的非虚拟 printImplDiscountUser::print.

调用的方法