gpt4 book ai didi

c++ - 如何扩展继承类的继承类

转载 作者:行者123 更新时间:2023-11-28 04:34:56 25 4
gpt4 key购买 nike

假设我有这个最小的例子:

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?由于转换不明确,我不断收到编译器错误。

注意:FooBar 来自一个库,所以我不能实现另一个接口(interface)来处理这个。

最佳答案

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; }
};

现在的问题是你不能继承自 FooInterface :您不能修改 Bar ,因此你不能让它虚拟继承,所以即使 Interface做了,你会得到两个 Foo 的实例在 MyClass .所以我的方法是在接口(interface)中引用 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++ - 如何扩展继承类的继承类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51751673/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com