C++ 当存在';涉及到什么接口?
我有一个提供classC++ 当存在';涉及到什么接口?,c++,inheritance,casting,polymorphism,C++,Inheritance,Casting,Polymorphism,我有一个提供classFoo的库。我在类FooExtended中使用自己的一些成员函数扩展Foo。为了在我的单元测试中使用FooExtended,我必须使其可模拟,因此我创建了一个接口IFoo,这就是我在整个代码库中使用的类型。然后,我创建了两个接口实现: 类FooMock-用于单元测试 类FooWrapper-在实际程序中使用。它主要是FooExtended的包装器,它作为成员存储一个实例 问题:问题在于FooWrapper。我不知道如何使用工厂Lib::create_foo()来创建库所
Foo
的库。我在类FooExtended
中使用自己的一些成员函数扩展Foo
。为了在我的单元测试中使用FooExtended
,我必须使其可模拟,因此我创建了一个接口IFoo
,这就是我在整个代码库中使用的类型。然后,我创建了两个接口实现:
- 类
-用于单元测试FooMock
- 类
-在实际程序中使用。它主要是FooWrapper
的包装器,它作为成员存储一个实例FooExtended
FooWrapper
。我不知道如何使用工厂Lib::create_foo()
来创建库所需的foo
,但也有我在FooExtended
中添加的my_added_函数()。dynamic_cast
失败
#include <iostream>
#include <memory>
#include <cassert>
using namespace std;
// What's in this namespace is in a 3rd party lib that I cannot change.
namespace Lib {
class Foo {
public:
virtual ~Foo() {};
int lib_func() {
return 42;
}
};
// Factory
Foo* create_foo() {
return new Foo();
}
} // namespace Lib
/** I want to extend the 3rd party class, and only use
this extended class in my project */
class FooExtended : public Lib::Foo {
public:
float my_added_func() {
return 1.0;
}
};
/** Interface for class Foo, created so that a mock
implementation of `FooExtended` can be created for unit tests. */
class IFoo {
public:
virtual int lib_func() = 0;
virtual float my_added_func() = 0;
};
/** Mock implemenation of IFoo for unit-tests. */
class FooMock : public IFoo() {
// Blah blah
}
/** Non-mock implementation of IFoo. Just a wrapper for the class with the
actual implementation, i.e. FooExtended. */
class FooWrapper : public IFoo {
public:
int lib_func() override {
assert(mFooExt); // This fails because dynamic_cast failed.
return mFooExt->lib_func();
};
float my_added_func() override {
assert(mFooExt); // This fails because dynamic_cast fails.
return mFooExt->my_added_func();
}
private:
unique_ptr<FooExtended> mFooExt {
unique_ptr<FooExtended>(
// This dynamic_cast fails.
dynamic_cast<FooExtended*>(Lib::create_foo()))
};
};
int main() {
unique_ptr<IFoo> foo { unique_ptr<IFoo>(new FooWrapper()) };
assert(foo != nullptr);
cout << "Starting...";
// Exits the program because of the assert inside.
cout << foo->lib_func() << "\n";
cout << foo->my_added_func();
}
#包括
#包括
#包括
使用名称空间std;
//这个名称空间中的内容位于我无法更改的第三方库中。
名称空间库{
福班{
公众:
虚拟~Foo(){};
int lib_func(){
返回42;
}
};
//工厂
Foo*创建_Foo(){
返回新的Foo();
}
}//名称空间库
/**我想扩展第三方类,并且只使用
这是我项目中的扩展类*/
类FooExtended:public Lib::Foo{
公众:
float my_added_func(){
返回1.0;
}
};
/**类Foo的接口,创建该接口是为了
可以为单元测试创建“FooExtended”的实现*/
类IFoo{
公众:
虚int lib_func()=0;
虚拟浮点my_added_func()=0;
};
/**单元测试IFoo的模拟实现*/
类FooMock:public IFoo(){
//废话
}
/**IFoo的非模拟实现。只是一个类的包装器
实际实施,即扩展。*/
类FooWrapper:public IFoo{
公众:
int lib_func()重写{
assert(mFooExt);//此操作失败,因为动态强制转换失败。
返回mFooExt->lib_func();
};
float my_添加了_func()覆盖{
assert(mFooExt);//由于动态强制转换失败,因此此操作失败。
返回mFooExt->my_added_func();
}
私人:
唯一的\u ptr mFooExt{
独特的(
//此动态_cast失败。
动态_cast(Lib::create_foo()))
};
};
int main(){
unique_ptr foo{unique_ptr(new FooWrapper())};
断言(foo!=nullptr);
cout如果您不怕为调用虚拟函数付出代价,您可以为Foo创建一个包装器,并在程序中使用它:
class IFoo {
public:
virtual ~Foo() {};
virtual int lib_func() = 0;
};
class MyFoo : public IFoo {
int lib_func() override { _foo.lib_func(); }
private:
std::unique_ptr<Foo> _foo = create_foo(); // pseudocode
};
类IFoo{
公众:
虚拟~Foo(){};
虚int lib_func()=0;
};
类MyFoo:公共IFoo{
int lib_func()重写{{u foo.lib_func();}
私人:
std::unique_ptr_foo=create_foo();//伪代码
};
现在您可以创建mock并将其用于IFoo。如果必须通过Foo*create\u Foo()
创建Foo的实例,那么您就不能从Foo
派生。FooExtended
的基类子对象显然不是也不能是由create\u Foo
创建的。最好的方法是创建一个包含(可能是智能的)指向Foo
作为成员的指针。虚拟函数成本?您有度量,在真实代码中?您知道比查表更好的解决方案?谢谢您的回答。您是对的:在这种情况下,我的扩展函数应该添加到包装器中,而不是添加到派生类footextended
。