오히려 여기 당신은 동적 기능에 대한 요구하고있다,하지만 큰 문제가 아니지만,이 인터페이스를 통해 노출되는 기능의 일부
반환 값하는 입력 매개 변수에 의해 결정됩니다 sKeyName.
C++은 정적으로 형식이 지정된 언어이므로 인수 값에 종속 된 함수의 반환 형식을 가질 수 없습니다. 당신이 살고하고자하는 경우,
struct SimpleDataAccess {
template <typename T>
array2d<T>* get_data(std::string const & which) {
return new array2d<T>();
}
};
int main() {
SimpleDataAccess accessor;
array2d<int> = accessor.get<int>("int"); // <int> at the place of call fixes
// the return type, not "int" !
}
현재 : 시간 인 상속 무시, 당신이 제시 한 코드는 독립적으로 전달 된 인수의반환되는 배열의 유형을 결정하기 위해 사용자가 필요 즉, 호출자는 반환 형식을 알고 설정합니다. 템플릿 가상 함수를 허용하지 않는 언어의 특정 문제에 대한 대안을 제공하는 여러 가지 방법이 있습니다. 우선 마음에 떠오르는 점은 NVI 관용구를 따르고 그 중요성을 보여주는 점에서 멋지다. 데이터에 가상이 아닌 공용 템플리트 액세서를 제공하고이를 고정 리턴 유형의 가상 함수로 구현한다.
class DataAccessor {
virtual Type get_data_impl(std::string const &) = 0;
public:
template <typename T>
array2d<T>* get_data(std::string const & which) {
Type tmp = get_data_impl(which);
return convert(tmp);
}
};
우리가 Type
및 convert
이 무엇인지 확인할 수 있다고 가정하면, 우리는 해결책을 가지고 있습니다. 이는 NVI 관용구의 좋은 예입니다. 사용자가 제공하는 인터페이스 (공개, 비 가상)는 확장 (개인, 가상)에 필요한 인터페이스와 다릅니다.두 계약이 다르다면 사용자가 구체적인 구체화 array2d
인스턴스화에 대한 포인터를 제공해야하지만 언어에서 사용자가 내선 번호와 동일한 계약을 요구할 수는 없지만 다른 인터페이스이기 때문에 문제가되지 않습니다.
이제는 Type
및 convert
으로 돌아갑니다. 이 두 가지는 서로 관련되어 있으며, 여러분이 따라야 할 다른 접근법이 있습니다. 모든 array2d<T>
이 파생 된에서 array2d_base
클래스를 낳게 될 것이다 구현하는 간단한 (당신이 RTTI 수 있도록 가상 소멸자를 제공하여) : 당신이 확장하거나 array2d
클래스를 변경할 수없는 경우
struct array2d_base {
virtual ~array2d_base() {}
};
template <typename T>
class array2d : public array2d_base {
// implementation
};
// Type == array2d_base*
// convert == dynamic_cast< array2d<T>* >
template <typename T>
array2d<T>* DataAccessor::get_data(std::string const & s) {
return dynamic_cast< array2d<T>* >(get_data_impl(s));
}
는, 당신은 유사한 결과를 얻을 수 있습니다 타입 소거에 의해. 이것은 array2d
에 RTTI를 요구하지 않고 유형 지우기 지원에서만 이점이 있습니다. 가장 간단한 구현 방법은 내부 인터페이스에 boost::any
을 사용하는 것입니다.
// Type == boost::any
// convert == boost::any_cast< array2d<T>* >
template <typename T>
array2d<T>* DataAccessor::get_data(std::string const & s) {
boost::any tmp = get_data_impl(s);
return boost::any_cast< array2d<T>* >(tmp);
}
Seams는 "묻지 마십시오."설계 원리를 깨고 있습니다. 정확히 당신이 보관하려고하는 것은 무엇입니까? –