关于c ++:将派生类转换为具有相同公共函数的泛型类类型,同时仍然能够调用派生类的函数

Convert derived class to generic class type with the same public functions, while still being able to call the function of the derived class

在以后的程序中,我有一个类动物,它派生出具有相同公共功能但不同私人功能的类猫和狗。我想让用户在运行时决定要创建哪个动物。我做了一个简单的例子,说明我大概想要什么,但显然不起作用。我不知道怎么解决这个问题,希望得到你的帮助。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <cstdio>

class canimal
{
  public:
    int sound()
    {
      std::printf("...
"
);
      return 0;
    }
};

class cdog : public canimal
{
  public:
    int sound()
    {
      std::printf("Woof!
"
);
      return 0;
    }
};

class ccat : public canimal
{
  public:
    int sound()
    {
      std::printf("Mieau!
"
);
      return 0;
    }
};

int main()
{
  canimal *animal;
  cdog    *dog;

  // I would like to let the user decide here which animal will be made
  // In this case, I would like the function to say"Woof!", but of course it doesn't...
  animal = new cdog;
  animal->sound();

  // Here it works, but I would like the pointer to be of the generic class
  // such that the type of animal can be chosen at runtime
  dog    = new cdog;
  dog->sound();

  return 0;
}


你需要制作sound()方法virtual

1
2
3
4
5
class canimal
{
  public:
    virtual int sound()
    ^^^^^^^

这将使它完全符合您的需要。

为了进一步讨论,为什么我们需要在C++中使用虚拟函数?

在C++ 11中有一个新的EDCOX1×2 }关键字,当适当使用时,使得某些类型的错误不太可能发生。请参见安全覆盖C++虚拟函数


你需要使用EDOCX1[1]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class canimal
{
  public:
    virtual int sound()
    {
      std::printf("...
"
);
      return 0;
    }
};

class cdog : public canimal
{
  public:
    virtual int sound()
    {
      std::printf("Woof!
"
);
      return 0;
    }
};

class ccat : public canimal
{
  public:
    virtual int sound()
    {
      std::printf("Mieau!
"
);
      return 0;
    }
};


我认为您希望使sound()成为虚拟的。读取C++中的多态性。

1
2
3
4
5
6
7
8
9
10
class canimal
{
  public:
    virtual int sound()
    {
      std::printf("...
"
);
      return 0;
    }
};