对继承的函数感到困惑

时间:2015-06-01 22:12:11

标签: c++ inheritance polymorphism

修正:修改如下:

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

用户类:

User class:
void print() made public

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

这是原帖:

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

继承类:

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

后来在另一堂课中我有:

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:&#39; User :: print&#39; :无法访问类&#39; User&#39;中声明的受保护成员。

我知道我得到它是因为它试图访问父类中的print()。是因为第三个代码片的第一行还是我真的搞砸了第四个代码中的指针?或者因为我是一个完全失败的人,我错过了一些明显的东西?

3 个答案:

答案 0 :(得分:3)

编译器通过查看指针的类型来了解应用哪些访问规则。由于指针是User *print在该类中受到保护,因此无法访问它。

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

除了编译错误之外,还有一个错误,因为writeFile正在按值而不是通过引用获取对象。为函数调用复制参数时,您将获得&#34;切片&#34;其中对象的类型被转换回基类。

答案 1 :(得分:1)

在C ++中,访问权限由变量的静态类型决定,而不是动态的。由于writeFile参数的静态类型为Userprintprotected,因此user的动态类型可能很重要碰巧是。

此外,您绝对应该通过引用(或指针)传递User个对象,而不是值。否则你会得到所谓的&#34;切片&#34;只复制一个对象的基础部分,这真的会给你带来麻烦。

答案 2 :(得分:1)

除了其他答案中讨论的问题之外,您还没有在virtual上使用User::print关键字。这意味着即使所有内容都是公共的,从User*变量调用它也总是会调用基本方法,即使该变量包含派生对象。

回顾最初的问题,我想知道你的意思是,在print中有一个公共的纯虚拟User方法,还有一个受保护的非虚拟printImpl方法。从DiscountUser::print调用。