重写模板类以使用继承而不改变需要静态函数调用的调用环境,但静态函数不能是虚拟的。
我从 C++ 编码测试中遇到了这个问题。实际上,这个问题并没有说得那么清楚,到目前为止我还没有得到解决方案。抱歉有任何歧义。为了帮助任何人更好地理解这个问题。以下是我个人的解读。欢迎指出我的误解。
该模板类是服务端封装的库,客户端调用一些静态函数等API。但是,静态函数不能是虚拟的。换句话说,静态函数不允许动态边界(覆盖)。
尝试重写一个模板类,这个类使用继承。所以这个类有一个派生类。但是我们不想改变 API 调用环境。换句话说,我们计划在服务器端升级代码,但我们不希望在客户端进行任何代码更改。
尝试使用继承,重写一个模板类。但是我们不想改变 API 调用环境。换句话说,我们计划在服务器端升级代码,但我们不希望在客户端进行任何代码更改。
我不确定 1 还是 2 是正确的解释。但我更倾向于1。在我看来,这个问题主要是测试的概念
- 服务端代码维护
- 设计模式,主要针对工厂方法
- 在类继承中覆盖静态函数的任何技巧
服务器端的原始代码:
#include<iostream>
using namespace std;
template<class T>
class Base
{
public:
Base(){}
Base(T B):m_B(B){}
virtual ~Base(){}
// Static method
static void speak()
{
cout << "I am Base class" << endl;
}
private:
T m_B;
};
template<class T>
class Derived: public Base<T>
{
public:
Derived(){}
Derived(T B, T D): Base<T>(B), m_D(D){}
~Derived(){}
// Static method
static void speak()
{
cout << "I am Derived class" << endl;
}
private:
T m_D;
};
客户端调用环境:
int main(int argc, char* argv[])
{
Base<int> *bPtr = new Derived<int>(5, 10);
bPtr->speak();
delete bPtr;
return 0;
}
输出:
我是基础班
(显然静态函数没有覆盖)
///////////////////////////////////////// //////////////////////////
我在服务器端重写了代码:
#include<iostream>
using namespace std;
template<class T>
class Base
{
public:
Base(){}
Base(T B):m_B(B){}
virtual ~Base(){}
// Static method
static void speak()
{
cout << "I am Base class" << endl;
}
// Non-static method
virtual void call_speak()
{
speak();
}
private:
T m_B;
};
template<class T>
class Derived: public Base<T>
{
public:
Derived(){}
Derived(T B, T D): Base<T>(B), m_D(D){}
~Derived(){}
// Static method
static void speak()
{
cout << "I am Derived class" << endl;
}
// Non-static method
void call_speak()
{
speak();
}
private:
T m_D;
};
template<class T>
class Factory
{
public:
// Return a base instance
static Base<T>* getInstance(T B)
{
Base<T> *bPtr = new Base<T>(B);
return bPtr;
}
// Return a derived instance
static Base<T>* getInstance(T B, T D)
{
Base<T> *bPtr = new Derived<T>(B, D);
return bPtr;
}
};
客户端调用环境:
int main(int argc, char* argv[])
{
Base<int> *bPtr = Factory<int>::getInstance(5, 10);
bPtr->speak();
bPtr->call_speak();
delete bPtr;
return 0;
}
输出:
我是基础班
我是派生类
我的修改:
- 为了“覆盖”静态函数,我添加了一个虚拟函数来调用静态函数作为技巧。
- 我使用工厂方法从客户端隐藏实例创建。
但我不确定这样的修改是否能满足不改变调用环境的要求。因为我确实在客户端更改了 API 调用。根据我的努力,这是我最好的解决方案。非常感谢任何评论和改进。