MQL5의 OOP에 대한 질문 - 페이지 79

 
Vladimir Simakov :

이 경우 전혀 비싸지 않습니다. 가상 메서드에 대한 비용이 많이 듭니다(액세스할 때 한 번의 역참조).

코드를 긁을 시간이 없었습니다. 방법은 다음과 같습니다.

JSONObject * CActor::getJSONObject( const string json) const
{
   JSONParser parser;
   JSONValue  *jv;
   JSONObject *jo = jv = parser.parse(json);
   if (jv != NULL && jv.isObject() && (EACTOR_TYPE)jo.getInt( "ActorType" ) == ActorType) return (jo);
   Print ( __FUNCTION__ + "parser error, json = " ,json);
   delete jv;
   delete jo;
   return ( NULL );
}

다음과 같이 작성할 수 있습니다(호출 결과는 일대일입니다. 즉, 모든 것을 올바르게 수행했습니다).

JSONObject * CActor::getJSONObject( const string json) const
{
   JSONParser parser;
   JSONValue  *jv = parser.parse(json);
   //JSONObject *jo = jv = parser.parse(json);
   if (jv != NULL && jv.isObject() && (EACTOR_TYPE)(((JSONObject *)jv).getInt( "ActorType" )) == ActorType) return ((JSONObject *)jv);
   Print ( __FUNCTION__ + "parser error, json = " ,json);
   delete jv;
   return ( NULL );
}

나는 이렇게 부른다.

JSONObject *jobj = getJSONObject(getStateIni());

저것들. 옵션 1과 2는 속도면에서 동일합니까? .... 물론, if()의 문자열 길이가 혼동 ... 읽기 어려운 코드 , 아마도 습관 때문일 것입니다.

 
Igor Makanu :

코드를 긁을 시간이 없었습니다. 방법은 다음과 같습니다.

다음과 같이 작성할 수 있습니다(호출 결과는 일대일입니다. 즉, 모든 것을 올바르게 수행했습니다).

나는 이렇게 부른다.

저것들. 옵션 1과 2는 속도면에서 동일합니까? .... 물론, if()의 문자열 길이가 혼동 ... 읽기 어려운 코드 , 아마도 습관 때문일 것입니다.

컴파일러에 의한 최적화 없이 일대일이면 두 번째가 더 빠릅니다. jo 포인터가 생성되거나 초기화되지 않습니다.

추신.

(JSONObject *)jv

불필요한. 그냥 jv를 반환

UPD: 간단히 말해서?
 if (jv!= NULL && jv.isObject() && jv.getInt( "ActorType" ) == (int)ActorType)
 
Vladimir Simakov :

UPD: 간단히 말해서?

JSONValue *jv에는 getInt() , getDouble() 메서드가 포함되어 있지 않습니다. 오류가 발생하고 JSONObject 유형이 필요합니다. 또는 이 유형으로 캐스트됩니다.

'getInt' - 어떤 오버로드도 함수 호출에 적용할 수 없습니다.

열거형을 int로 변환하고 싶지 않습니다 - 댓글 쓰기가 너무 게으르면 무엇과 비교했는지 알 수 없으며 눈으로 읽을 수 있기 때문에 열거 형이 흥미 롭습니다.

고맙습니다!

 
Igor Makanu :

JSONValue *jv에는 getInt() , getDouble() 메서드가 포함되어 있지 않습니다. 오류가 발생하고 JSONObject 유형이 필요합니다. 또는 이 유형으로 캐스트됩니다.

'getInt' - 어떤 오버로드도 함수 호출에 적용할 수 없습니다.

열거형을 int로 변환하고 싶지 않습니다 - 댓글 쓰기가 너무 게으르면 무엇과 비교했는지 알 수 없으며 눈으로 읽을 수 있기 때문에 열거 형이 흥미 롭습니다.

고맙습니다!

JSONValue:public JSONObject가 없나요?
 
Vladimir Simakov :
JSONValue:public JSONObject가 없나요?

그렇게 작동하지 않습니다

github의 라이브러리, 여기에 첨부된 소스가 있습니다. https://www.mql5.com/en/forum/85652/page72#comment_16758982

KB https://www.mql5.com/en/code/11134 의 초기 버전(다운로드하지 않음) - 사용 예도 있습니다.

 
Igor Makanu :

그렇게 작동하지 않습니다

github의 라이브러리, 여기에 첨부된 소스가 있습니다. https://www.mql5.com/en/forum/85652/page72#comment_16758982

KB https://www.mql5.com/en/code/11134 의 초기 버전(다운로드하지 않음) - 사용 예도 있습니다.

Mdyaya... 여기에 UB가 있습니다. 상속인에게 캐스트할 수는 없지만 상속인에 대한 포인터를 만들고 올바른 포인터의 값을 할당하여 문제를 해결했습니다. 다 괜찮지만 일단
parser.parse(json)

JSONObject*를 반환하지 않으며 모든 것이 런타임에 떨어집니다.)))

그리고 당연히 그렇습니다)) 베이스에서 후계자로 직접 캐스팅할 수 없습니다. 이것은 UB( UNDEFINED BEHAVIOR )입니다. 프로에서 이렇게 하면 아무 것도 떨어지지 않지만 ... (가능성에 대한 농담이 있습니다. 신이 왕을 구하는 동안 처형) )))

바르게:

JSONObject* jv = dynamic_cast <JSONObject*>(parser.parse(json));
if (jv != NULL && jv.getInt( "ActorType" ) == ActorType) return jv;

그리고 dynamic_cast의 비용에 대해 이야기하기 시작하는 첫 번째 사람 - 질문과 함께 죽입니다. 런타임이 캐스트가 잘못되었음을 어떻게 알 수 있습니까?

 
Vladimir Simakov :
1) Mdyaya... 여기에 UB가 있습니다. 상속인에게 캐스트할 수는 없지만 상속인에 대한 포인터를 만들고 올바른 포인터의 값을 할당하여 문제를 해결했습니다.
모든 것이 정상이지만 JSONObject가 아닌 *을 반환하는 즉시 모든 것이 런타임에 떨어집니다.)))

그리고 당연히 그렇습니다))) 베이스에서 후계자로 직접 캐스팅할 수는 없습니다. 이것은 UB( UNDEFINED BEHAVIOR )입니다. 프로에서 이 작업을 수행하면 아무 것도 떨어지지 않지만 ...(가능성에 대한 농담이 있습니다. 신이 왕을 구하는 동안 처형) )))

2) 맞습니다: 그리고 dynamic_cast의 비용에 대해 이야기하기 시작하는 첫 번째 사람 - 질문과 함께 죽입니다. 런타임이 캐스트가 잘못되었음을 어떻게 알 수 있습니까?

1) 사용하지 않는 jv.isObject() 메소드를 통해 객체의 실제 타입을 확인하기 때문에 UB가 없고 non-JSONObject*가 반환되어도 떨어지지 않는다.
2) JSONObject 를 기본 클래스로 사용하는 라이브러리의 다음 버전에 새 데이터 유형 이 나타나면 작동하지 않을 수 있는 예입니다.

 
Sergey Dzyublik :

1) 사용하지 않는 jv.isObject() 메소드를 통해 객체의 실제 타입을 확인하기 때문에 UB가 없고 non-JSONObject*가 반환되어도 떨어지지 않는다.
2) JSONObject 를 기본 클래스로 사용하는 라이브러리의 다음 버전에 새 데이터 유형 이 나타나면 작동하지 않을 수 있는 예입니다.

 JSONObject * CActor::getJSONObject( const string json) const
{
   JSONParser parser;
   JSONValue  *jv;
   JSONObject *jo = jv = parser.parse(json);
   if (jv != NULL && jv.isObject() && (EACTOR_TYPE)jo.getInt( "ActorType" ) == ActorType) return (jo);
   Print ( __FUNCTION__ + "parser error, json = " ,json);
   delete jv;
   delete jo;
   return ( NULL );
}

강조 표시됨. 다음 줄만 확인))) 예에서 작성자는 둘 중 하나를 정반대로 먼저 확인하고 캐스팅)

UPD: dynamic_cast는 양방향으로 작동함)

UPD2: JSONObject 의 후계자가 있다면 왜 넘어야 합니까?

 
Vladimir Simakov :
Mdyaya... 여기에 UB가 있습니다.
UB가 없으며 mql 캐스트에는 dynamic_cast도 포함되어 있습니다. 잘못된 포인터의 경우 모든 것이 떨어질 것입니다.
 
Andrei Trukhanovich :
UB가 없으며 mql 캐스트에는 dynamic_cast도 포함되어 있습니다. 잘못된 포인터의 경우 모든 것이 떨어질 것입니다.

동의합니다)) 저는 플러스 쪽입니다)))

사유: