c++ - 如何改写一个template class,该类含有static function,使得对外API调用接口不改变?

浏览:39日期:2023-06-04

问题描述

由于担心中文翻译产生歧义,附上英文原题目:Rewrite template classes to use inheritance without changing the calling environment which required a static function call, but static functions can’t be virtual. 英文原题描叙地址

我感觉题目大概意思是,需要改写或更新一个服务端的class,使得客户端调用相关API的时候,不需要修改接口。这里我只想到了用工厂模式来解决,当然不确定对不对。另外,static function是不能够virtual,所以继承的时候,静态函数重写(overriden)是不允许,有没有方式解决这个问题?

总的来说,我觉得此题考点包含三个:

Code maintenance in server side

Design pattern, mainly for factory method

Any trick to overide static function in class inheritance

当然我不确定对题目的理解有没有错误。其实我不是很确定题目是想问,用继承的方式来重新修改这个class?还是重新修改这个类,这个类被其它子类继承了?

我目前还没有找到最佳答案。所以我先给出当前我能想到的答案。欢迎大家的补充和修正。万分感谢THX!!

The original code in server side:

#include<iostream>using namespace std;template<class T>class Base{ public:Base(){}Base(T B):m_B(B){}virtual ~Base(){}// Static methodstatic 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 methodstatic void speak(){ cout << 'I am Derived class' << endl;}private:T m_D; };

The calling environment in client side:

int main(int argc, char* argv[]){ Base<int> *bPtr = new Derived<int>(5, 10); bPtr->speak(); delete bPtr; return 0;}

Output:

I am Base class

(obviously no overrding for static function)

////////////////////////////////////////////////////////////////////////////////

My rewrote code in server side:

#include<iostream>using namespace std;template<class T>class Base{ public:Base(){}Base(T B):m_B(B){}virtual ~Base(){}// Static methodstatic void speak(){ cout << 'I am Base class' << endl;}// Non-static methodvirtual 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 methodstatic void speak(){ cout << 'I am Derived class' << endl;}// Non-static methodvoid call_speak(){ speak(); } private:T m_D; };template<class T>class Factory{ public:// Return a base instancestatic Base<T>* getInstance(T B){ Base<T> *bPtr = new Base<T>(B); return bPtr;}// Return a derived instancestatic Base<T>* getInstance(T B, T D){ Base<T> *bPtr = new Derived<T>(B, D); return bPtr;}};

The calling environment in client side:

int main(int argc, char* argv[]){ Base<int> *bPtr = Factory<int>::getInstance(5, 10); bPtr->speak(); bPtr->call_speak(); delete bPtr; return 0;}

Output:

I am Base class

I am Derived class

主要修改:

使用了工厂模式,把产生对象的过程隐藏起来。

用虚非静态函数的方式重新封装静态函数。

问题解答

回答1:

试了一下,我感觉题主对题目的理解有误。我对题目的理解:

without changing the calling environment说的是不改变调用环境,也就是不能修改题目中的main函数,而你的解法修改了main函数。

下面是我对题目的总结:

use inheritance

一定要使用继承。

required a static function call

说的是speak一定要是一个static函数。

without changing the calling environment

不修改main函数

在这三个条件下,我能想到的唯一解法就是类模板特化。我用模板特化解决了问题,但是有一个题目中的要求没有满足,就是Rewrite template classes。我的方法没有修改任何类,只是新加了两个特化类,而且speak貌似变成了virtual的。下面是我的解法

template<>class Base<int>{ public:Base(){}Base(int B):m_B(B){}virtual ~Base(){}virtual void speak(){ cout << 'I am Base class' << endl;} private:int m_B; };

template<>class Derived<int>: public Base<int>{ public:Derived(){}Derived(int B, int D): Base<int>(B), m_D(D){}~Derived(){}// Static methodvirtual void speak(){ cout << 'I am Derived class' << endl;}private:int m_D; };

相关文章: