我遇到了实施工厂方法的一些变化的问题。
// from IFoo.h
struct IFoo {
struct IBar {
virtual ~IBar() = 0;
virtual void someMethod() = 0;
};
virtual IBar *createBar() = 0;
};
// from Foo.h
struct Foo : IFoo { // implementation of Foo, Bar in Foo.cpp
struct Bar : IBar {
virtual ~Bar();
virtual void someMethod();
};
virtual Bar *createBar(); // implemented in Foo.cpp
};
我想在Foo.cpp
中声明Foo :: Bar的声明。现在我不能成功:
struct Foo : IFoo {
//struct Bar; //1. error: invalid covariant return type
// for ‘virtual Foo::Bar* Foo::createBar()’
//struct Bar : IBar; //2. error: expected ‘{’ before ‘;’ token
virtual Bar *createBar();
// virtual IBar *createBar(); // Is not acceptable by-design
};
是否有一个技巧可以在Boo
中直接声明Foo.hpp
并在Foo.cpp
中进行完整声明?
编辑: 看起来,我没有显示错误。 S®,有更详细的样本。
首次尝试前瞻声明:
struct Foo : IFoo {
struct Bar;
virtual Bar *createBar(); //<- Compile-error
};
//error: invalid covariant return type for ‘virtual Foo::Bar* Foo::createBar()’
第二次尝试前瞻声明:
struct Foo : IFoo {
struct Bar : IBar; //<- Compile-error
virtual Bar *createBar();
};
// error: expected ‘{’ before ‘;’ token
有人可以提供更改createBar
的退货类型(从Bar
到IBar
)
struct Foo : IFoo {
virtual IBar *createBar();
};
但是,这种解决方法不能被设计
答案 0 :(得分:1)
不,你不能转发声明某个子类。
当然,既然你要隐藏课程细节,你可以添加另一层次的间接。
struct IFoo {
struct IBar {
virtual ~IBar() = 0;
virtual void someMethod() = 0;
};
virtual IBar *createBar() = 0;
};
// from Foo.h
struct Foo : IFoo {
struct Bar : IBar {};
virtual Bar *createBar();
};
// In Foo.cpp
struct FooBar : Foo::Bar
{
virtual ~FooBar() {}
virtual void someMethod()
{
// Do stuff...
}
};
Foo::Bar* Foo::createBar()
{
return new FooBar;
}
答案 1 :(得分:0)
当然,您可以对嵌入式类进行前向声明。但是,只有实现文件Foo.cpp中才能访问Bar和IFoo :: IBar的关系。
foo.h中:
struct Foo : IFoo {
struct Bar;
virtual IBar *createBar();
};
Foo.cpp中:
struct FooBar::Bar
{
/* define the nested class here */
};
答案 2 :(得分:0)
您甚至不需要在Foo类中声明Bar子类型。栏可以完全隐藏在源文件中。
这个例子说明了我的意思:
#include <functional>
#include <iostream>
#include <utility>
struct IFoo {
struct IBar {
virtual ~IBar(){}
virtual void someMethod() = 0;
};
virtual IBar *createBar() = 0;
};
// from Foo.h
struct Foo : IFoo { // implementation of Foo, Bar in Foo.cpp
virtual IBar *createBar(); // implemented in Foo.cpp
};
namespace {
struct HiddenBar : IFoo::IBar
{
virtual void someMethod(){
std::cout<<"I am IBar type"<<std::endl;
}
};
}
IFoo::IBar* Foo::createBar()
{
return new HiddenBar;
}
int main() {
Foo foo;
auto bar = foo.createBar();
bar->someMethod();
}
请注意,HiddenBar应该对外界不可见,并且只能通过它的界面访问。但这意味着要修复Foo::createBar()
方法的签名。
另一种方法是在Foo中完全声明Foo :: Bar。没有办法解决它。