【问题标题】:Function overload for pointer to abstract class指向抽象类的指针的函数重载
【发布时间】:2017-03-05 03:23:48
【问题描述】:

我在 C++ 中的函数重载方面遇到了一些问题。

我有一个类层次结构,其中许多类继承自一个抽象基类,如下所示:

struct Animal {
  virtual void make_noise() = 0;
};

struct Dog : Animal {
  void make_noise() { std::cout << "bark\n"; }
};

struct Cat : Animal {
  void make_noise() { std::cout << "meow\n"; }
};

struct Lion : Cat {
  void make_noise() { std::cout << "roar\n"; }
};

我想要一个根据参数类型具有三种不同实现的函数:

  • 一个用于指向Animal 的子类的指针:Dog *Lion * 等。
  • 一个用于指向Animal 子类的指针向量:std::vector&lt;Animal *&gt;std::vector&lt;Lion *&gt; 等。
  • 每个其他类型都有一个,即使是那些不是指针的类型:char *std::stringint 等。

这是我的尝试:

void f(Animal *x) {
  x->make_noise();
}

void f(std::vector<Animal *> x) {
  std::cout << "vector\n";
}

template<class T>
void f(T a) {
  std::cout << a << "\n";
}

int main() {
  f(new Lion);
  std::vector<Animal *> x;
  f(x);
  f(2);
  return 0;
}

这是上面程序打印的内容:

0x7febb8d00000
vector
2

这是我想要打印的内容:

roar
vector
2

此外,如果我尝试传递 std::vector&lt;Lion *&gt; 而不是 std::vector&lt;Animal *&gt;,它会选择最后一个实现而不是第二个实现并生成编译器错误。

如何在 C++98 中解决这个问题?

【问题讨论】:

  • 对于声明者来说,无论如何,带有std::vector&lt;Animal *&gt; 参数的函数不会接受std::vector&lt;Lion *&gt;。这两个向量模板实例是不同的类,彼此之间没有任何关系。仅仅因为一个模板的参数是指向另一个模板参数的基类的指针,并不会使第一个模板成为第二个模板的派生类。 C++ 不能以这种方式工作。我认为您需要花更多时间研究模板和类在 C++ 中的工作原理,并首先了解一些基础知识。

标签: c++ oop inheritance overloading c++98


【解决方案1】:

一种方法是使用模板特化并在对 f 的调用中指定模板参数类型,如下所示:

template<class T>
void f(T a) {
  std::cout << a << "\n";
}

template<>
void f(Animal *x) {
  x->make_noise();
}

template<>
void f(std::vector<Animal *> x) {
  std::cout << "vector\n";
}


int main() {
  f<Animal *>(new Lion); // specify template param
  std::vector<Animal *> x;
  f(x);
  f(2);
  return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-28
    • 1970-01-01
    • 1970-01-01
    • 2015-03-02
    • 1970-01-01
    相关资源
    最近更新 更多