use*_*420 6 c++ polymorphism multiple-inheritance
在 C++ 中可以将函数参数定义为一种以上类型吗?
#include <iostream>
using namespace std;
class A {
public:
void PrintA() { cout << "A" << endl;}
};
class B {
public:
void PrintB() { cout << "B" << endl;}
};
class C: public A, public B {
public:
C(){;}
};
class D: public A, public B {
public:
D(){;}
};
///
void __printall__(A*a, B*b){
a->PrintA();
b->PrintB();
}
#define printall(a) __printall__(a,a)
///
int main(int argc, char *argv[]){
C c;
D d;
printall(&c);
printall(&d);
}
Run Code Online (Sandbox Code Playgroud)
我想用不使用宏的东西更改注释之间的代码。我不会强制转换指针,因为我想保留类型安全。我什至不会在 C/D 和 A/B 之间引入另一个类,因为实际上我的类层次结构比代码中显示的要复杂一些,并且不希望对从 A 或 B 派生的所有类进行重新设置
就像@Torsten 建议的那样,一个可能的解决方案是使用函数模板,以便您可以传递任何类型的参数。但是,简单的模板将适用于提供适当成员的任何类型(在本例中printA为 和printB),因此以下函数模板
template <typename T>
void printAll(T const & t)
{
t.printA();
t.printB();
}
Run Code Online (Sandbox Code Playgroud)
将与以下类型一起使用
struct Foo
{
void printA() const { std::cout << "FooA\n"; }
void printB() const { std::cout << "FooB\n"; }
}
printAll(Foo());
Run Code Online (Sandbox Code Playgroud)
即使Foo不是派生自Aor B。这可能是可取的,但如果您确实想强制执行参数必须是 aA和 a 的事实B,您可以在函数中使用静态断言来检查:
#include <type_traits>
template <typename T>
void printAll(T const & t)
{
static_assert(std::is_base_of<A, T>::value && std::is_base_of<B, T>::value,
"T must be derived from A and B");
t.printA();
t.printB();
}
Run Code Online (Sandbox Code Playgroud)
另一种解决方案是std::enable_if仅当模板参数确实是A和的派生类时才使用定义函数模板B:
template<
typename T ,
typename = typename std::enable_if<
std::is_base_of<A, T>::value &&
std::is_base_of<B, T>::value
>::type
>
void printAll(T const & t)
{
t.printA();
t.printB();
}
Run Code Online (Sandbox Code Playgroud)
注意:static_assert、enable_if和is_base_of是 C++11 功能。如果您使用 C++03,则可以在各种 Boost 库中找到等效项。
模板版本只会选择传递给函数的类型:
template < class T >
void printall( T* t )
{
t->printA();
t->printB();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4788 次 |
| 最近记录: |