Nếu bạn không muốn sử dụng tăng/C++ 17 nào, hãy xem xét thu được những tham số của chức năng 'doSometing' từ một lớp cơ sở, và làm diễn viên năng động để đối tượng lớp phù hợp. Trong trường hợp này, bạn có thể kiểm tra trong thời gian chạy mà bạn có một con trỏ hợp lệ.
class param{
public:
virtual ~param(){};
};
template <typename T>
struct specificParam:param{
specificParam(T p):param(p){}
T param;
};
class Foo
{
public:
virtual void doSomething(param* data) = 0;
};
template <typename T>
class Bar : public Foo
{
public:
virtual void doSomething(param* data){
specificParam<T> *p = dynamic_cast<specificParam<T> *>(data);
if (p != nullptr){
std::cout<<"Bar got:" << p->param << "\n";
}
else {
std::cout<<"Bar: parameter type error.\n";
}
}
};
int main(){
Bar<char> obj1;
Bar<int> obj2;
Bar<float> obj3;
specificParam<char> t1('a');
specificParam<int> t2(1);
specificParam<float> t3(2.2);
obj1.doSomething(&t1); //Bar got:a
obj2.doSomething(&t2); //Bar got:1
obj3.doSomething(&t3); //Bar got:2.2
// trying to access int object with float parameter
obj2.doSomething(&t3); //Bar: parameter type error.
}
Cách đơn giản nhất (nhưng không an toàn!) Sẽ được sử dụng con trỏ void * + cast tĩnh
class Foo
{
public:
virtual void doSomething(void* data) = 0;
};
template <typename T>
class Bar:public Foo
{
public:
virtual void doSomething(void* data){
T* pData = static_cast<T*>(data);
std::cout<<"Bar1 got:" << *pData << "\n";
}
};
int main(){
Bar<char> obj1;
Bar<int> obj2;
Bar<float> obj3;
char c = 'a';
int i = 1;
float f = 2.2;
obj1.doSomething(&c); // Bar1 got:a
obj2.doSomething(&i); // Bar1 got:1
obj3.doSomething(&f); // Bar1 got:2.2
//obj2.doSomething(&c); // Very bad!!!
}
bạn có thể xin được cụ thể hơn? Làm cách nào để bạn sử dụng dữ liệu bên trong hàm? Yêu cầu của loại dữ liệu là gì? Ví dụ. chỉ có một vài lớp được biết đến, hoặc bạn có kế hoạch chấp nhận bất kỳ lớp nào có một phương thức cụ thể, vv? – bolov
Câu hỏi của bạn cần được thu hẹp một chút. Bạn có biết phạm vi của các loại, bạn có muốn chúng được tự động suy luận không? Câu trả lời đơn giản nhất sẽ là "sử dụng void *", một câu trả lời tốt hơn có thể là câu trả lời của Story Teller. Tất cả phụ thuộc vào usecase của bạn. –
Tôi tò mò, nhìn vào các câu trả lời, về nếu có bất kỳ khả năng để đạt được kết quả tương tự mà không cần phải làm bất kỳ đúc trên 'doSomething'. Một cái gì đó giống như đóng gói kiểu theo cách nào đó mà không cần phải tạo mẫu 'doSomething' và lấy kiểu đó bằng' decltype', tức là kiểu phương thức nhà máy ảo ... – perencia