如何扩展继承类的继承类
How to extend an inherited class's inherited class
>假设我有这个最小的例子:
class BaseClass {
void method1();
};
class Foo : public BaseClass {
void method1();
};
class Bar : public Foo {
void method1();
}
class Interface : public Foo {
};
class MyClass : public Interface, public Bar {
}
在实现MyClass
时,如何告诉编译器Bar
正在扩展Interface
中的Foo
?由于转换不明确,我不断收到编译器错误。
注意:Foo
和Bar
来自库,所以我不能仅仅实现另一个接口来处理这个问题。
class Foo
{
public:
virtual ~Foo() { }
virtual void f() { std::cout << "foo!" << std::endl; }
};
class Bar : public Foo
{
public:
void f() override { std::cout << "bar!" << std::endl; }
};
现在的问题是您无法从Interface
中的Foo
继承: 你不能修改Bar
,因此你不能让它虚拟继承,所以即使Interface
这样做了,你也会在MyClass
得到两个Foo
实例。所以我的方法是在接口中引用Foo,并提供一个明确的强制转换:
class Interface
{
Foo& foo;
protected:
Interface(Foo& foo) : foo(foo) { }
public:
operator Foo&()
{
return foo;
}
virtual ~Interface() { }
// this actually is only a short cut - you can always
// access Foo's f via cast as well!
// (so you can drop it, if you prefer)
virtual void f() { foo.f(); }
};
class MyClass : public Interface, public Bar
{
public:
MyClass() : Interface(*static_cast<Foo*>(this)) { }
using Bar::f;
};
现在您可以按如下方式使用它:
MyClass c;
Interface* i = &c;
Foo* f = &static_cast<Foo&>(*i);
// or, if you have not yet lost access to c, simply:
f = &static_cast<Foo&>(c);
扩展:如果您需要能够直接实例化Interface
(而不是以派生类的形式(,您可以通过对Interface
进行一些小的修改来实现这一点:
class Interface
{
Foo* foo; // raw pointer even in times of C++11 and smart pointers:
// need to be able to delete c o n d i t i o n a l l y
bool isOwner;
protected:
Interface(Foo& foo) : foo(&foo), isOwner(false) { }
public:
Interface() : foo(new Foo()), isOwner(true) { }
operator Foo&()
{
return *foo;
}
virtual ~Interface()
{
if(isOwner)
{
delete foo;
}
}
virtual void f() { foo->f(); }
};
编辑:虽然上述内容通常有效,但如果您尝试通过指针删除Interface
(非派生Foo
,则会遇到麻烦。您可以按如下方式解决问题:
class Interface
{
Foo& foo;
protected:
Interface(Foo& foo) : foo(foo) { }
public:
operator Foo&()
{
return foo;
}
virtual ~Interface() { }
//virtual void f() { foo.f(); }
};
class MyFoo : public Interface, public Foo
{
public:
MyFoo() : Interface(*static_cast<Foo*>(this)) { }
virtual ~MyFoo() { }
//using Foo::f; // don't need, if dropping the short cut
};
class MyBar : public Interface, public Bar
{
public:
MyBar() : Interface(*static_cast<Foo*>(this)) { }
virtual ~MyBar() { }
//using Bar::f; // don't need, if dropping the short cut
};
虽然现在Foo
继承自Bar
,但MyBar
不是从MyFoo
继承的,所以你不能将MyBar
对象分配给MyFoo
指针。但是你们都可以(通过演员表(分配给一个Foo
指针,根据讨论的问题,这是你的实际目标,所以这应该没问题......
相关文章:
- 继承函数的重载解析
- 继承期间显示未知行为的子类
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 如何扩展继承类的继承类
- variadic模板扩展,继承和std :: unique_ptr
- 从可变参数模板中的扩展 decltype 继承
- 我想继承 SPIFFS 类来扩展它以用于我的方法.可能吗
- 当可变参数模板类继承自模板参数时,在调用基类型的方法时扩展参数包
- 继承Java集合接口(Set、Map、List等)的C++等价物是什么?或者扩展AbstractCollection
- 我们可以用自定义函数扩展现有的类吗?(无继承)
- 在C++中扩展容器(如std::vector)功能的正确方法,而不从中继承
- 在C++中扩展继承的数组
- C++类扩展(继承类中数组的不同大小)
- 使用继承扩展接口
- 通过多重私有继承扩展类-这是一件事吗
- 通过继承实现类似"二维"扩展的设计类
- 在继承类中扩展结构
- 同一类的 C++ 扩展构造函数(无继承)
- 提振.扩展-简单的继承示例-为什么我们在linux上看不到动物
- 通过继承扩展shared_ptr