描述从多个接口派生的对象
Describing an object that derives from multiple interfaces
在C++中,我有两个纯抽象类(Viewable和Movable),可能有许多类型从其中一个或两个接口派生(Dog、Duck、Cat)。
我想定义一个接受单个参数的函数,其中该参数实现两个接口。据我所知,在C++中,一个对象只能有一个静态类,所以我正在尝试想出不同的方法来解决这个问题。
下面的方法go1
采用Viewable和Movable两个参数。如果我有一个类似Dog
的类型,它派生了两个接口,那么我可以调用go1(d, d)
。但是,我想防止go1(d, c)
,其中c
和d
是不同的对象(可能具有不同的类)。
我可以创建一个从Movable和Viewable派生的新类型MovableAndViwable
,但这需要我将类的定义更改为从MovableAndViwable派生,而不是从两个单独的接口派生。此外,如果我有很多接口,并且想将这个想法扩展到两种以上的类型,我最终会得到很多"混合"类型(例如,MovableAndViewableAndSavableAndRunnableAndRestorable…)
所以我的问题是:是否有银弹来解决我所描述的问题。请参阅我的示例代码中的方法go3
——我想用一种方法向编译器描述一个对象从两个或多个不同且不相关的C++类派生而来。
此外,我对我的类的其他设计感兴趣,现在想知道除了C++之外的其他语言如何解决这个问题(假设我不需要使用C++)。
#include <iostream>
struct Movable { virtual void move() const = 0; };
struct Viewable { virtual void view() const = 0; };
struct MovableAndViewable : Movable, Viewable {};
struct Dog : virtual Movable, virtual Viewable {
void move() const { std::cout << "Movingn"; }
void view() const { std::cout << "Viewingn"; }
};
struct Duck : virtual Movable, virtual Viewable {
void move() const { std::cout << "Movingn"; }
void view() const { std::cout << "Viewingn"; }
};
struct Cat : virtual MovableAndViewable {
void move() const { std::cout << "Movingn"; }
void view() const { std::cout << "Viewingn"; }
};
struct Fish : virtual Movable {
void move() const { std::cout << "Movingn"; }
};
void go1(Movable const &m, Viewable const &v) { m.move(); v.view(); }
void go2(MovableAndViewable const &mv) { mv.move(); mv.view(); }
//void go3(Movable and Viewable const &mv) { mv.move(); mv.view(); }
int main()
{
Dog d;
Cat c;
Fish f;
go1(d, d);
//go1(f, f); // Nope, Fish isn't Viewable
//go2(d);
go1(c, c);
go2(c);
//go3(d);
//go3(c);
return 0;
}
下面的方法怎么样。它似乎满足了您传递单个参数的期望目标:
class Movable {
public:
virtual void move()=0;
};
class Viewable {
public:
virtual void view()=0;
};
// A stub class, used for parameter passing.
class MovableAndViewable {
public:
Movable &m;
Viewable &v;
public:
template<typename m_and_v> MovableAndViewable(m_and_v &object)
: m(object), v(object)
{
}
};
// Passing only a single parameter:
void go2(const MovableAndViewable &mv)
{
mv.m.move();
mv.v.view();
}
// Example:
class MV : public Movable, public Viewable {
public:
void move()
{
}
void view()
{
}
};
void go3()
{
MV mv;
go2(mv);
}
然后,另外我还要声明:
class const_MovableAndViewable {
public:
const Movable &m;
const Viewable &v;
public:
template<typename m_and_v> const_MovableAndViewable(const m_and_v &object)
: m(object), v(object)
{
}
};
// In order to be able to pass references to const objects:
void const_go2(const const_MovableAndViewable &mv);
您可以使用动态铸造。这允许您访问实例继承的任何类型。
有一个更通用的基类可能会很有用,这样在设计函数时就不必在接口之间进行选择(base
是一个常用的类型名称)。
- 为什么此派生对象无法访问基类的后递减方法?
- 如何在新的派生对象中获取基本对象的数据?
- 如何将成员函数作为参数传递并在派生对象上执行方法列表
- 在没有默认构造函数的情况下创建的派生对象
- OOP 标识派生对象
- 如何创建派生对象的向量?
- 将基类分配给派生对象,反之亦然,以C++以及静态和动态对象之间的差异
- 如何从 Gtk::窗口调用派生对象的析构函数
- 无法在派生对象上运行虚拟函数
- 尝试删除指向派生对象的基指针时断言错误
- 存储在一个通用容器中的派生对象.如何避免铸造
- 将派生对象分配给函数内的基类指针
- 替换派生对象向量中的对象"no matching function to call"
- 派生对象调用的 Base 方法的模板推导
- 用于填充 Base 和派生对象的 shared_ptr 向量的函数模板
- C++ UBSAN 对派生对象产生误报
- 如何验证我是否正在使用C++中的基对象或派生对象
- C++ 构造函数和派生对象
- 将派生对象传递给模板
- 指向派生作品的基本指针,即使派生对象不存在