模板 class 实现存在编译问题
Template class implementation has compilation issues
我正在使用 class 的静态成员函数创建一个对象。然后在里面调用一个函数。
int main(){
int a = 49;
auto foo = Foo::createFoo(a);
foo->study();
}
实施
对于此示例,让 study()
显示一个值。
在结构方面,我确实有限制,必须有下面的接口,然后是返回对象的静态方法
class I_Foo{
public:
virtual void study(void) = 0;
};
class Foo : public I_Foo{
public:
static Foo* createFoo(int x_) {
return new Foo(x_);
}
void study() override{
std::cout << "studied: "<< st << std::endl;
}
protected:
Foo(int a) : st(a) {}
int st = 0;
};
上述实现绝对有效,正如预期的那样即变量 a
应显示为 studied: a
现在我想改变这个
的行为
假设对于低于 50 的值,上述实现应保持 “不变” ,即变量 a
应显示为 studied: a
但是,当值变为 50 及以上时,输出应显示 studied: a+100
#include <iostream>
class I_Foo{
public:
virtual void study(void) = 0;
};
template<int>
class FooImpl;
class Foo : public I_Foo {
public:
static Foo* createFoo(int x_) {
Foo* foo = nullptr;
if (x_>=50) {
foo = new FooImpl<2>(x_);
}
else {
foo = new FooImpl<1>(x_);
}
return foo;
}
};
template<int FT = 1>
class FooImpl : public Foo{
public:
void study() override{
std::cout << "studied: "<< st << std::endl;
}
FooImpl(int a) : st(a) {}
int st = 0;
};
template<>
void FooImpl<2>::study() override{
std::cout << "studied: "<< st + 100 << std::endl;
}
int main()
{
int a = 56;
auto foo = Foo::createFoo(a);
foo->study();
}
这显然无法编译,因为 Foo
不知道 FooImpl
是什么!
请建议我如何才能完成这项工作。要求是保持主要功能不变,但具有新功能。
请注意
是的,我知道这可以通过 if 语句解决,但这不是重点。它在现实中有一个复杂的实现,我只是试图将它呈现在一个相当容易理解的问题中,以研究这些模板如何工作。
编辑 1
第一次编辑后,我看到以下编译错误
正如我在评论中所写:不要在 class 声明中实现 createFoo
函数。
#include <iostream>
class I_Foo {
public:
virtual void study(void) = 0;
};
class Foo : public I_Foo {
public:
// here just DECLARE the method...
static Foo *createFoo(int x_);
};
/********/
/* SNIP */
/********/
// ...and IMPLEMENT it there
Foo *Foo::createFoo(int x_) {
if (x_>=50) {
return new FooImpl<2>(x_);
} else {
return new FooImpl<1>(x_);
}
}
int main() {
int a = 56;
auto foo = Foo::createFoo(a);
foo->study();
}
我正在使用 class 的静态成员函数创建一个对象。然后在里面调用一个函数。
int main(){
int a = 49;
auto foo = Foo::createFoo(a);
foo->study();
}
实施
对于此示例,让 study()
显示一个值。
在结构方面,我确实有限制,必须有下面的接口,然后是返回对象的静态方法
class I_Foo{
public:
virtual void study(void) = 0;
};
class Foo : public I_Foo{
public:
static Foo* createFoo(int x_) {
return new Foo(x_);
}
void study() override{
std::cout << "studied: "<< st << std::endl;
}
protected:
Foo(int a) : st(a) {}
int st = 0;
};
上述实现绝对有效,正如预期的那样即变量 a
应显示为 studied: a
现在我想改变这个
的行为
假设对于低于 50 的值,上述实现应保持 “不变” ,即变量 a
应显示为 studied: a
但是,当值变为 50 及以上时,输出应显示 studied: a+100
#include <iostream>
class I_Foo{
public:
virtual void study(void) = 0;
};
template<int>
class FooImpl;
class Foo : public I_Foo {
public:
static Foo* createFoo(int x_) {
Foo* foo = nullptr;
if (x_>=50) {
foo = new FooImpl<2>(x_);
}
else {
foo = new FooImpl<1>(x_);
}
return foo;
}
};
template<int FT = 1>
class FooImpl : public Foo{
public:
void study() override{
std::cout << "studied: "<< st << std::endl;
}
FooImpl(int a) : st(a) {}
int st = 0;
};
template<>
void FooImpl<2>::study() override{
std::cout << "studied: "<< st + 100 << std::endl;
}
int main()
{
int a = 56;
auto foo = Foo::createFoo(a);
foo->study();
}
这显然无法编译,因为 Foo
不知道 FooImpl
是什么!
请建议我如何才能完成这项工作。要求是保持主要功能不变,但具有新功能。
请注意 是的,我知道这可以通过 if 语句解决,但这不是重点。它在现实中有一个复杂的实现,我只是试图将它呈现在一个相当容易理解的问题中,以研究这些模板如何工作。
编辑 1
第一次编辑后,我看到以下编译错误
正如我在评论中所写:不要在 class 声明中实现 createFoo
函数。
#include <iostream>
class I_Foo {
public:
virtual void study(void) = 0;
};
class Foo : public I_Foo {
public:
// here just DECLARE the method...
static Foo *createFoo(int x_);
};
/********/
/* SNIP */
/********/
// ...and IMPLEMENT it there
Foo *Foo::createFoo(int x_) {
if (x_>=50) {
return new FooImpl<2>(x_);
} else {
return new FooImpl<1>(x_);
}
}
int main() {
int a = 56;
auto foo = Foo::createFoo(a);
foo->study();
}