C ++ void 포인터의 유형을 찾으십시오
-
19-09-2019 - |
문제
작은 질문이 있습니다 : A C ++ Pointer 유형이 무엇인지 어떻게 알 수 있습니까?
나는 종종 콘솔 프로그램에서 작은 기능을 사용하여 입력을 수집합니다.
void query(string what-to-ask, [insert datatype here] * input)
빈 공간 포인터를 사용하여 일반적인 형태를 만들고 싶지만 공허 포인터를 묶을 수는 없으므로 유형을 찾아서 캐스트 할 수있는 방법을 찾는 방법은 무엇입니까?
해결책
내가 C ++로 코딩 한 마지막 이래로 오랜 시간이 지났지 만 ...
당신은 a를 사용할 수 없습니다 주형?
다른 팁
당신은 할 수 없습니다.
그러나 한 가지 대안은 무효 포인터를 없애고 모든 것이 공통 기본 클래스에서 파생되고 RTTI를 사용하는 것입니다.
An example:
class Base
{
public:
virtual ~Base() {}
};
class Foo : public Base { /* ... */ };
void SomeFunction(Base *obj)
{
Foo *p = dynamic_cast<Foo*>(obj);
if (p)
{
// This is of type Foo, do something with it...
}
}
통과하는 대신 a void*
그 주변에는 올바른 유형으로 캐스트해야합니다. 읽을 모든 유형과 함께 사용할 수있는 템플릿 기능을 사용해야합니다.
이렇게하면 유형-안전 코드를 얻을 수 있으며 대부분의 입력 유형에 대한 특수 코드를 작성할 필요가 없습니다.
template<typename T>
void query(const string &whattoask, T &input) {
cout << whattoask << endl;
cin >> input;
cout << endl;
}
int main() {
int i;
double d;
string s;
query("An integer: ", i);
query("Floating point: ", d);
query("A word: ", s);
}
void*
형식입니다 모두 데이터가 있습니다. 당신은 그것을 "결정"할 수 없습니다 ~이다 프로그램에있는 모든 데이터 ~이다 void*
! 그렇습니다. 그들은 디자인에 따라 기억의 생생한 덩어리입니다.
너 ~할 수 있었다 코드를 사용하여 전체 코드를 프로그램하십시오 void*
뿐. 운 좋게도 C 언어는 추가 기능을 제공합니다 편의 당신에게, 당신은 그들이 아닌 것처럼 일부 데이터를 조작하게합니다. void*
. 그러나이 편의를 사용하려면 캐스팅해서는 안됩니다. void*
그리고 그들이 어떤 유형인지 잊어 버리십시오.
당신의 질문은 나에게 전혀 명확하지 않지만 아마도 당신이 원하는 것은 과부하하는 것입니다. query
void query(string what2ask, int* input) {
cout << what2ask;
cin >> *input;
}
void query(string what2ask, float* input) {
cout << what2ask;
cin >> *input;
}
int age;
float sqrt2;
query("How old are you?", &age);
query("What's the square root of 2?", &sqrt2);
당신이 요구하는 것을 이해한다면, 이것을하는 일반적인 방법은 지원하는 인터페이스 클래스를 만드는 것입니다. query(string what-to-ask)
그런 다음 무효 포인터를 사용하는 대신 포인터를 인터페이스로 전달하십시오. 그런 다음 해당 인스턴스에서 Query ()를 호출 할 수 있습니다.
아니요. 당신은 이것을 할 수 없습니다. 이와 같은 것이 필요한 경우 제안합니다 boost.any.
데이터 타입을 직접 제어하면 아마도 당신이 관심을 갖고 모든 데이터 유형의 열거를 포함하는 클래스/구조물을 만들고 그것을 전달할 것입니다. 그런 다음 전달 된 포인터로 데이터 유형을 쿼리 한 다음 적절하게 캐스트 할 수 있습니다.
IE (의사 코드 경고 - 지금은 이것을 구조물로 취급하십시오.)
class MyDataType {
enum aDataType type;
void * myData;
}
void query( string whatToAsk, MyDataType * pdata)
{
switch ( pdata.type) {
case integer:
int * workInt = (int * ) pdata;
do whatever you want to to get the data
break;
case someFunkyObject:
someFunkyObject pob = (SomeFunkyObject *) pdata;
Do whatever you want with the data.
etc.
}
}
char *로 읽은 다음 문자열 (char)을 구문 분석하여 int, float, string, 뭐든지 결정할 수 있습니다. 까다로운 부분은 그것을 변환하는 것입니다.
예를 들어:
문자열의 각 문자에 대해
if (캐릭터는 '입니다.')
++ DecimalCount
else if (캐릭터는 편지입니다)
++ LetterCount
루프의 끝
DecimalCount> 0 && LetterCount == 0 인 경우 각 숫자를 통해 오른쪽에서 왼쪽으로 구문 분석하고 10의 전력을 곱하고 합계를 추가합니다.
그렇지 않으면 decimalcount == 1 && lettercount == 0
플로트가 바이너리에 어떻게 표현되는지 배우고 다른 사람의 기능을 찾으십시오.
그렇지 않으면 LetterCount> 0
그것은 문자열입니다. 예!
가능하면 무효 포인터를 피하고 템플릿을 사용하십시오. 나는 최근에 많은 공허 *가있는 거대한 코드 기반을 찾고 있습니다. 시간이 많이 걸립니다.