앗. 지원 질문 - 페이지 15

 

기본 생성자는 해당 클래스의 객체 배열을 초기화할 때 특별한 목적을 가지고 있습니다. 모든 매개변수가 기본값으로 설정된 생성자는 기본 머신아닙니다 . 여기 .

오타를 빨간색으로 강조 표시했습니다.

그런데 이러한 생성자가 기본 생성자가 아닌 이유는 무엇입니까? 또 다른 목발?

 
TheXpert :

기본 생성자는 해당 클래스의 객체 배열을 초기화할 때 특별한 목적을 가지고 있습니다. 모든 매개변수가 기본값으로 설정된 생성자는 기본 머신아닙니다 . 여기

흥미로운 오타, 감사합니다. 결정된.
 
Yedelkin :

" 유효하지 않은 포인터 접근 " == " 유효하지 않은 포인터 접근을 시도했습니다"?

종종 비뚤어진 손의 직접적인 징후이거나 포인터 작업의 기본 원칙에 대한 이해 부족입니다.

덜 자주 클래스 사용에 대한 문서 부족의 징후입니다.

 
TheXpert :

그런데 이러한 생성자가 기본 생성자가 아닌 이유는 무엇입니까? 또 다른 목발?

정반대. 목발은 기본 매개변수의 존재입니다. 이것이 미묘한 버그의 원인이기 때문입니다. 여기서 우리는 엄격함을 보여주었습니다.

매개변수가 있는 생성자를 작성하면 매개변수가 없는 생성자도 작성할 수 있습니다. 그리고 기본 생성자가 있는 경우 모든 기본 매개변수를 사용하여 매개변수 생성자를 작성할 수 없습니다.

 
stringo :

목발은 기본 매개변수의 존재입니다. 이것이 미묘한 버그의 원인이기 때문입니다.

예, 어떻게 든 그러한 상황을 생각할 수 없습니다.

기본 생성자가 있으면 모든 기본 매개변수를 사용하여 매개변수 생성자를 작성할 수 없습니다.

아, 그렇다면 당연하고 논리적입니다. 그리고 이해할 수 없는 이중성이 드러났습니다.
 

컨텍스트 확인 작업( :: )에 대해 읽었습니다. 나는 두 개의 관련 없는 클래스에서 사용하기로 결정했습니다.

 //+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class C_B;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class C_A
  {
public :
   C_B              *pointer;

                     C_A( void ) {};
                    ~C_A( void ) {};
   void funcA( int i) { Print( "funcA(" ,i, ")=" ,i); }
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class C_B
  {
public :
                     C_B( void ) {};
                    ~C_B( void ) {};
   void funcB( int j)
     {
      Print( "funcB(" ,j, ")=" ,j);
      C_A::funcA(j);
     }
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
  {
   C_A object ;
   object .pointer= new C_B();
   object .pointer.funcB( 5 );
   delete object .pointer;
  }

컴파일러는 C_A::funcA(j) 행에서 오류를 발생시킵니다. 주석 처리하면 작동하는 것 같습니다. 내 실수가 뭐야?

 
Yedelkin :

컨텍스트 확인 작업( :: )에 대해 읽었습니다. 나는 두 개의 관련 없는 클래스에서 사용하기로 결정했습니다.

컴파일러는 C_A::funcA(j) 행에서 오류를 발생시킵니다. 주석 처리하면 작동하는 것 같습니다. 내 실수가 뭐야?

귀하의 경우 클래스 C_A의 컨텍스트는 클래스 C_B에서 액세스할 수 없습니다.

다음과 같은 경우에만 정확합니다.

 //+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class C_B : public C_A
  {
public :
                     C_B( void ) {};
                    ~C_B( void ) {};
   void funcB( int j)
     {
      Print( "funcB(" ,j, ")=" ,j);
      C_A::funcA(j);
     }
  };

하지만 다음을 수행할 수 있습니다.


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class C_B : public C_A
  {
public :
                     C_B( void ) {};
                    ~C_B( void ) {};
   void funcB( int j)
     {
      Print( "funcB(" ,j, ")=" ,j);
      funcA(j);
     }
  };


일반적으로 이러한 호출은 오버로드된 메서드에 사용됩니다.


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class C_B;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class C_A
  {
public :
   C_B              *pointer;

                     C_A( void ) {};
                    ~C_A( void ) {};
   void func( int i) { Print( "C_A::func(" ,i, ")=" ,i); }
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class C_B : public C_A
  {
public :
                     C_B( void ) {};
                    ~C_B( void ) {};
   void func( int j)
     {
      Print( "C_B::func(" ,j, ")=" ,j);
      C_A::func(j);
     }
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
  {
   C_A object ;
   object .pointer= new C_B();
   object .pointer.func( 5 );
   delete object .pointer;
  }

다소 이렇습니다.

 
uncleVic :

귀하의 경우 클래스 C_A의 컨텍스트는 클래스 C_B에서 액세스할 수 없습니다.

고맙습니다. 그래서 컨텍스트 해석 연산 을 상속 없이 적용할 수 있다고 착각했다.
 

설명자의 도움을 받아 "참조로" 한 클래스에서 다른 클래스로 멤버 값을 전달하려고 합니다. 두 옵션 모두 작동하는 것 같습니다. 다음은 가장 간단한 다이어그램입니다.

 class B
  {
private :
   double             d1;
public :
                     B( double &d) {  d1=d; Print ( "class B, double d1=" ,d1);  };
                    ~B( void ){};
  };
class A
  {
public :
   double             double_var;
   A                *pointerA;
 

                     A( void ) : double_var( 1.234567 ),pointerA( NULL ) { SetPointer(); };
                    ~A( void ) { if ( CheckPointer (pointerA)== POINTER_DYNAMIC ) delete pointerA; };
private :
   void SetPointer( void ) { pointerA= GetPointer ( this ); }
  };
class C 
  {
public :
   A                *pointerA_C;
public :
                     C( void ) : pointerA_C( NULL ) {};
                    ~C( void ) { if ( CheckPointer (pointerA_C)== POINTER_DYNAMIC ) delete pointerA_C;};
   void Printer() { if ( CheckPointer (pointerA_C)!= POINTER_INVALID ) Print ( "class C, double =" ,pointerA_C.double_var); };
  };
void OnStart ()
  {
   A objA;
//---передаём значение double-переменной по ссылке
   B objB(objA.double_var);
//---передаём значение double-переменной через описатель
   C objC;
   objC.pointerA_C=objA.pointerA;
   objC.Printer();
  }

이 두 가지 방법 중 어느 것이 더 빠릅니까? 어느 것이 바람직합니까?

 
Yedelkin :

설명자의 도움을 받아 "참조로" 한 클래스에서 다른 클래스로 멤버 값을 전달하려고 합니다. 두 옵션 모두 작동하는 것 같습니다. 다음은 가장 간단한 다이어그램입니다.

이 두 가지 방법 중 어느 것이 더 빠릅니까? 어느 것이 바람직합니까?

정말 어려운/잘못된 질문은 무엇입니까?

오랫동안 첫 번째 방법("참조로")을 사용했지만 설명자에 대한 아이디어가 정말 마음에 들었습니다. 그것 때문에 모든 클래스를 다시 작성할 가치가 있는지 모르겠습니다.