오류, 버그, 질문 - 페이지 2356

 
A100 :

C++: A::f()

이 코드는 무엇을 보여줍니까?

((A*)&b).f();
 
fxsaber :

이 코드는 무엇을 보여줍니까?

똑같다.

 
Ilya Malev :

똑같다.

MQL로(C++로 변환된 경우). 하지만 직접 확인할 수 있습니다
 
A100 :
MQL로(C++로 변환된 경우). 하지만 직접 확인할 수 있습니다

확인됨:


 
Ilya Malev :

확인됨:

나는 당신이 뭔가를 확인하고 있다고 생각하지 않습니다.

B*b1=a;

MQL의 그러한 레코드는 객체 a -를 포인터 b1에 위치한 객체로 복사하는 것을 의미합니다. 일반적으로 당연히 컴파일되어서는 안됩니다.

그리고 힙에 있는 객체와 포인터를 방해하지 않으려면 포인터에 p 접두사를 사용하는 것이 좋습니다.

 
Ilya Malev :

확인됨:

이 잘못된 행동에 베팅하지 마십시오.

2가지 문제(?)가 있습니다.

  1. B *b1=a - 명확한 오류, 컴파일러는 이 구성을 복사 연산자 A::A(const A &)에 대한 호출로 인식합니다.

  2. 첫 번째 경우에 옵티마이저는 A::A(const A &)가 비어 있고 멤버가 없으며 "포인터"로 액세스할 수 없다고 결정했습니다(사실, 복사 연산자를 호출할 코드가 남아 있지 않았고 모든 것이 잘렸습니다).
    virtual B::f()는 오버로드되지 않으므로 가상 호출 대신 간단했습니다. B::f()에는 구성원에 대한 주소 지정이 없으므로 "포인터"에 의한 액세스도 차단되었습니다.

    두 번째 경우 A::f()는 가상 호출을 시도하고 "포인터"에 의한 액세스가 있지만 객체 a1이 없기 때문에 A *a1=b의 경우 빈 복사 생성자 A::A(const A &)에 대한 호출도 있었습니다.
 
Ilyas :

이 잘못된 행동에 베팅하지 마십시오.

2가지 문제(?)가 있습니다.

이 잘못된 동작을 수정하기를 바랍니다. (make a compilation error ) 실수로 그런 실수를 할 수 있고 컴파일러는 어떤 식으로든 반응하지 않기 때문입니다.

 
Alexey Navoykov :

이 잘못된 동작을 수정하기를 바랍니다. 실수로 그러한 오류를 범할 수 있고 컴파일러가 어떤 식으로든 반응하지 않기 때문입니다.

네, 수정하겠습니다.

우선 순위가 낮음으로 설정되어 있기 때문에 빈 클래스에 대해서만 작업 코드를 얻습니다.

 
Ilyas :

이 잘못된 행동에 베팅하지 마십시오.

2가지 문제(?)가 있습니다.

  1. B *b1=a - 명확한 오류, 컴파일러는 이 구성을 복사 연산자 A::A(const A &)에 대한 호출로 인식합니다.

  2. 첫 번째 경우에 옵티마이저는 A::A(const A &)가 비어 있고 멤버가 없으며 "포인터"로 액세스할 수 없다고 결정했습니다(사실, 복사 연산자를 호출할 코드가 남아 있지 않았고 모든 것이 잘렸습니다).
    virtual B::f()는 오버로드되지 않으므로 가상 호출 대신 간단했습니다. B::f()에는 구성원에 대한 주소 지정이 없으므로 "포인터"에 의한 액세스도 차단되었습니다.

    두 번째 경우 A::f()는 가상 호출을 시도하고 "포인터"에 의한 액세스가 있지만 객체 a1이 없기 때문에 A *a1=b의 경우 빈 복사 생성자 A::A(const A &)에 대한 호출도 있었습니다.

자세한 답변 감사합니다만, 논리를 조금 이해하지 못했습니다.

1) 컴파일러는 왜 B* b1=a 구성을 복사 연산자 A:: A(const A&)에 대한 호출로 인식하고 B:: B(const A&)에 대한 호출이 아닌 것으로 인식합니까? 연산자의 왼쪽 =)

2) 컴파일러에서 "복사 생성자 누락" 경고가 발생하지 않은 이유

3) 존재하지 않는 객체에 대해 "간단한" 메서드 호출이 허용되는 이유(B::f()를 직접 호출하려고 하는 동안 "비 정적 메서드 호출" 컴파일 오류가 발생함)

4) 컴파일러가 일반적으로 가상 메서드에 대한 "단순한" 호출을 허용하는 이유는 무엇입니까? 제 생각에는 가상이 객체에 있는 데이터의 존재 여부에 의존해서는 안 됩니다.

 
Ilya Malev :

1) 컴파일러는 왜 B* b1=a 구성을 복사 연산자 A:: A(const A&)에 대한 호출로 인식하고 B:: B(const A&)에 대한 호출이 아닌 것으로 인식합니까? 연산자의 왼쪽 =)

맞아요. 컴파일러가 다음과 같이 자유롭게 허용하는 또 다른 MQL 버그입니다. B b = a; 이것은 캡슐화 원칙에 위배됩니다. C++에서 이것은 자연스럽게 컴파일되지 않으므로 명시적 캐스트가 필요합니다. 그리고 MQL의 이전 빌드에서는 이것을 하는 것도 불가능했습니다.