c++ - 如何改写一个template class,该类含有static function,使得对外API调用接口不改变?
黄舟
黄舟 2017-04-17 12:08:27
0
1
650

由于担心中文翻译产生歧义,附上英文原题目: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)是不允许,有没有方式解决这个问题?

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

  1. Code maintenance in server side

  2. Design pattern, mainly for factory method

  3. 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 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;
    
};

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 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;
        }
};

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. 使用了工厂模式,把产生对象的过程隐藏起来。

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

黄舟
黄舟

人生最曼妙的风景,竟是内心的淡定与从容!

membalas semua(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 method
        virtual void speak()
        {
            cout << "I am Derived class" << endl;
        }
    
    private:
        int m_D;
    
};
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan