Перепишите классы шаблонов, чтобы использовать наследование без изменения вызывающей среды, для которой требовался статический вызов функции, но статические функции не могут быть виртуальными.
Я сталкивался с этим вопросом из теста C ++. На самом деле, этот вопрос не так четко сформулирован, и у меня пока нет решения. Извините за любую неясность. Чтобы помочь кому-то лучше понять этот вопрос. Ниже приводится моя личная интерпретация. Добро пожаловать, чтобы указать на мое недоразумение.
Этот шаблонный класс является инкапсулированной библиотекой на стороне сервера, некоторые API, такие как статическая функция, вызываются на стороне клиента. Однако статическая функция не может быть вирулентной. Другими словами, динамическое ограничение (переопределение) для статической функции не допускается.
Попробуйте переписать шаблонный класс, и этот класс использует наследование. Таким образом, этот класс имеет производный класс. Но мы не хотим менять среду вызова API. Другими словами, мы планируем обновить код на стороне сервера, но не хотим никаких изменений кода на стороне клиента.
Попробуйте использовать наследование, чтобы переписать класс tempalte. Но мы не хотим менять среду вызова 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 на стороне клиента. Исходя из моих усилий, это мое лучшее решение. Очень ценю любые комментарии и улучшения.
Задача ещё не решена.
Других решений пока нет …