operator 연산자도 상속이 가능한가요?

nayana의 이미지

부모 클래스에 ( operator= )연산자가 있을 경우
자식 클래스에서 부모클래스의 operator 연산자를 사용할수 있나요?

doldori의 이미지

부모 클래스의 대입연산자가 public이라면 사용은 할 수 있지만 상속은 안됩니다.
생성자, 소멸자, 대입연산자, 프렌드는 상속되지 않습니다.

nayana의 이미지

부모클래스에 a()( 당연히 public 혹은 protected )라는 멤버 함수 있고 자식 클래스에서 a()라는 멤버 함수를 호출 하면 상속이
가능한것 처럼 operator 연산자 함수( 당연히 public 혹은protected )를 자식 클래스에서 호출하면 상속이 아닌가요?

doldori의 이미지

일반적인 public 멤버라면 상속이 됩니다만 개체의 생성, 소멸, 복사에 관한 멤버는
특별한 의미를 갖기 때문에 각 클래스에서 책임지고 정의하게 되어 있습니다.

class B
{
public:
    void f();
    B& operator=(const B&);
};

class D : public B { };

D d1, d2;
d1.f();  // (1)
d1 = d2; // (2)

이때 (1)에서 호출하는 함수는 B::f()입니다. 상속받았으므로 당연한 얘기죠.
그러나 (2)에서는 그렇지 않습니다. D::operator=()가 호출됩니다. 이 함수는
컴파일러가 대신 만들어 주기 때문에 눈에 보이지 않을 뿐 B::operator=()와는
다른 함수입니다. 이것이 상속받은 멤버와의 차이입니다.
nayana의 이미지

일단 답변에 감사드립니다.
그래서 제 나름대로 예제를 하나 만들어 보았습니다.

      1 #include <cstdio>
      2 #include <new>
      3
      4 //========================================================================================================================
      5 template < class DataType >
      6 class xCParentsOperation
      7 {
      8 public :
      9     inline xCParentsOperation( int p_size );
     10           ~xCParentsOperation( );
     11
     12     inline void      NamolaPrintInfo( void );
     13     inline DataType& operator[] ( int p_index );
     14
     15 private :
     16     DataType* m_Alloc;
     17     int       m_Size;
     18 };
     19 //========================================================================================================================
     20
     21 //------------------------------------------------------------------------------------------------------------------------
     22 template < class DataType >
     23 inline
     24 xCParentsOperation< DataType >::xCParentsOperation( int p_size )
     25     :m_Alloc( 0 )
     26 //------------------------------------------------------------------------------------------------------------------------
     27 {
     28     m_Alloc = new DataType[ p_size ];
     29     if ( !m_Alloc ) return NULL;
     30
     31     m_Size  = p_size;
     32 }
     33
     34 //------------------------------------------------------------------------------------------------------------------------
     35 template < class DataType >
     36 xCParentsOperation< DataType >::~xCParentsOperation()
     37 //------------------------------------------------------------------------------------------------------------------------
     38 {
     39     if ( m_Alloc ) delete[] m_Alloc;
     40     m_Alloc = 0;
     41 }
     42
     43 //------------------------------------------------------------------------------------------------------------------------
     44 template < class DataType >
     45 inline
     46 DataType& xCParentsOperation< DataType >::operator[] ( int p_index )
     47 //------------------------------------------------------------------------------------------------------------------------
     48 {
     49     return m_Alloc[ p_index ];
     50 }
     51
     52 //------------------------------------------------------------------------------------------------------------------------
     53 template < class DataType >
     54 inline
     55 void xCParentsOperation< DataType >::NamolaPrintInfo( void )
     56 //------------------------------------------------------------------------------------------------------------------------
     57 {
     58     printf( "부모 멤버 함수 호출\n" );
     59 }
     60
     61 //========================================================================================================================
     62 template < class DataType >
     63 class xCChildOperation : public xCParentsOperation< DataType >
     64 {
     65 public :
     66     xCChildOperation( int Size = 1 );
     67     ~xCChildOperation();
     68
     69 private :
     70     DataType* m_ChildAlloc;
     71     int       m_ChildSize;
     72 };
     73 //========================================================================================================================
     74
     75 //------------------------------------------------------------------------------------------------------------------------
     76 template < class DataType >
     77 xCChildOperation< DataType >::xCChildOperation( int Size )
     78     :xCParentsOperation( Size ), m_ChildAlloc( 0 )
     79 //------------------------------------------------------------------------------------------------------------------------
     80 {
     81     m_ChildAlloc = new DataType[ Size ];
     82     if ( !m_ChildAlloc ) return NULL;
     83
     84     m_ChildSize = Size;
     85 }
     86
     87 //------------------------------------------------------------------------------------------------------------------------
     88 template < class DataType >
     89 xCChildOperation< DataType >::~xCChildOperation()
     90 //------------------------------------------------------------------------------------------------------------------------
     91 {
     92     if ( m_ChildAlloc ) delete[] m_ChildAlloc;
     93     m_ChildAlloc = 0;
     94 }
     95
     96 int main ( void )
     97 {
     98     xCChildOperation< int > a1( 10 );
     99     a1.NamolaPrintInfo();
    100
    101     /*
    102     a1[ 0 ] = 1;
    103
    104     int i = a1[ 0 ];
    105
    106     printf( "a1[ 0 ] => %d\n", i );
    107     */
    108
    109     return 0;
    110 }

다음과 같은 오류가 납니다. 연산자 부분은 주석 처리를 했는데...

xCOperator.cpp: In constructor
   `xCChildOperation<DataType>::xCChildOperation(int)':
xCOperator.cpp:78: class `xCChildOperation<DataType>' does not have any field
   named `xCParentsOperation'
xCOperator.cpp: In constructor
   `xCChildOperation<DataType>::xCChildOperation(int) [with DataType = int]':
xCOperator.cpp:98:   instantiated from here
xCOperator.cpp:80: no matching function for call to `xCParentsOperation<int>::
   xCParentsOperation()'
xCOperator.cpp:7: candidates are:
   xCParentsOperation<int>::xCParentsOperation(const xCParentsOperation<int>&)
xCOperator.cpp:25:
   xCParentsOperation<DataType>::xCParentsOperation(int) [with DataType = int]
xCOperator.cpp:98:   instantiated from here
xCOperator.cpp:82: returning a value from a constructor
doldori의 이미지

질문하신 내용과는 별로 관계가 없는 에러로군요.

template < class DataType > 
xCChildOperation< DataType >::xCChildOperation( int Size ) 
    :xCParentsOperation( Size ), m_ChildAlloc( 0 )   //  (1)
{ 
    m_ChildAlloc = new DataType[ Size ]; 
    if ( !m_ChildAlloc ) return NULL;                // (2)

    m_ChildSize = Size; 
} 

(1)에서 기초 클래스 부분을 초기화할 때는
xCParentsOperation<DataType>( Size )
으로 써야 합니다.
그리고 생성자는 반환값이 없으므로 (2)처럼 쓸 수는 없습니다.
생성자에서 뭔가 잘못되었으면 보통 예외를 던지는 식으로 처리합니다.
nayana의 이미지

그렇군요...다시 수정했습니다.

      1 #include <cstdio>
      2 #include <iostream>
      3
      4 using std::cout;
      5 using std::endl;
      6
      7 #include <new>
      8
      9 using std::bad_alloc;
     10
     11 //========================================================================================================================
     12 template < class DataType >
     13 class xCParentsOperation
     14 {
     15 public :
     16     inline xCParentsOperation( int p_size );
     17           ~xCParentsOperation( );
     18
     19     inline void      NamolaPrintInfo( void );
     20     inline DataType& operator[] ( int p_index );
     21
     22 private :
     23     DataType* m_Alloc;
     24     int       m_Size;
     25 };
     26 //========================================================================================================================
     27
     28 //------------------------------------------------------------------------------------------------------------------------
     29 template < class DataType >
     30 inline
     31 xCParentsOperation< DataType >::xCParentsOperation( int p_size )
     32     :m_Alloc( 0 )
     33 //------------------------------------------------------------------------------------------------------------------------
     34 {
     35     try
     36     {
     37         m_Alloc = new DataType[ p_size ];
     38     }
     39     catch( bad_alloc &memoryAllocationException )
     40     {
     41         cout << "메모리 할당 실패 : "
     42              << memoryAllocationException.what() << endl;
     43     }
     44
     45     m_Size  = p_size;
     46 }
     47
     48 //------------------------------------------------------------------------------------------------------------------------
     49 template < class DataType >
     50 xCParentsOperation< DataType >::~xCParentsOperation()
     51 //------------------------------------------------------------------------------------------------------------------------
     52 {
     53     if ( m_Alloc ) delete[] m_Alloc;
     54     m_Alloc = 0;
     55 }
     56
     57 //------------------------------------------------------------------------------------------------------------------------
     58 template < class DataType >
     59 inline
     60 DataType& xCParentsOperation< DataType >::operator[] ( int p_index )
     61 //------------------------------------------------------------------------------------------------------------------------
     62 {
     63     return m_Alloc[ p_index ];
     64 }
     65
     66 //------------------------------------------------------------------------------------------------------------------------
     67 template < class DataType >
     68 inline
     69 void xCParentsOperation< DataType >::NamolaPrintInfo( void )
     70 //------------------------------------------------------------------------------------------------------------------------
     71 {
     72     printf( "부모 멤버 함수 호출\n" );
     73 }
     74
     75 //========================================================================================================================
     76 template < class DataType >
     77 class xCChildOperation : public xCParentsOperation< DataType >
     78 {
     79 public :
     80     inline xCChildOperation( int Size = 1 );
     81     ~xCChildOperation();
     82
     83 private :
     84     DataType* m_ChildAlloc;
     85     int       m_ChildSize;
     86 };
     87 //========================================================================================================================
     88
     89 //------------------------------------------------------------------------------------------------------------------------
     90 template < class DataType >
     91 inline
     92 xCChildOperation< DataType >::xCChildOperation( int Size )
     93     :xCParentsOperation< DataType >( Size ), m_ChildAlloc( 0 )
     94 //------------------------------------------------------------------------------------------------------------------------
     95 {
     96     try
     97     {
     98         m_ChildAlloc = new DataType[ Size ];
     99     }
    100     catch( bad_alloc &memoryAllocationException )
    101     {
    102         cout << "메모리 할당 실패 : "
    103              << memoryAllocationException.what() << endl;
    104     }
    105
    106
    107     m_ChildSize = Size;
    108 }
    109
    110 //------------------------------------------------------------------------------------------------------------------------
    111 template < class DataType >
    112 xCChildOperation< DataType >::~xCChildOperation()
    113 //------------------------------------------------------------------------------------------------------------------------
    114 {
    115     if ( m_ChildAlloc ) delete[] m_ChildAlloc;
    116     m_ChildAlloc = 0;
    117 }
    118
    119 int main ( void )
    120 {
    121     xCChildOperation< int > a1( 10 );
    122     a1.NamolaPrintInfo();
    123
    124
    125     a1[ 0 ] = 1;
    126
    127     int i = a1[ 0 ];
    128
    129     printf( "a1[ 0 ] => %d\n", i );
    130
    131
    132     return 0;
    133 }

디버깅을 해보게 되면 a1[ 0 ] = 1 함수에서 부모 클래스 operator 연산자 부분을 호출하게 됩니다. 이부분은 어떻게 되는건지요?
doldori의 이미지

윽... 지금까지 operator[]를 말씀하신 것이었습니까? :?
처음에 대입연산자(operator=)라고 하시길래 저는 계속 그쪽만 생각했네요.
operator[]는 당연히 상속됩니다.

nayana의 이미지

처음에는 operator= 이것으로 질문 하였는데....
operator 연산자는 아무거나 만들어도 상관 없다는 생각에
operator[] 연산자를 만들었습니다.

D::operator=()가 호출됩니다. 이 함수는 
컴파일러가 대신 만들어 주기 때문에 눈에 보이지 않을 뿐 B::operator=()와는 
다른 함수입니다. 이것이 상속받은 멤버와의 차이입니다

그러면 operator 연산자는 상속 가능한 연산자가 있고 상속이 가능하지 못한 연산자가 있는건가요?

doldori의 이미지

operator=, 생성자, 소멸자, 프렌드만 상속이 안됩니다.
위에서 말씀드린 대로 그 의미가 특별하기 때문입니다.

mr.lee의 이미지

지금 이슈는 제가 진행하고 있는 스마트포인터를 이용한 프로젝트와 중요한 연관이 있기 때문에 테스트를 해 보았습니다.

상속도 잘 되고, 오버로딩도 잘 되는것 같은데 틀린 부분이 있으면 지적하여 주시기 바랍니다.

오버로딩

#include <iostream>

using namespace std;

class A {
    public:
        A& operator=(const A&) { cout << "A" << endl; }
};

class B : public A {
    public:
        B& operator=(const B&) { cout << "B" << endl; }
};

int main() {
    A a, b;
    a = b;
    B c, d;
    c = d;
    return 0;
}

출력

A
B

상속

#include <iostream>

using namespace std;

class A {
    public:
        A& operator=(const A&) { cout << "A" << endl; }
};

class B : public A {};

int main() {
    A a, b;
    a = b;
    B c, d;
    c = d;
    return 0;
}

출력

A
A
nayana의 이미지

신기하게도 operator= 연산자도 상속이 가능합니다.

      1 #include <cstdio>
      2 #include <iostream>
      3
      4 using std::cout;
      5 using std::endl;
      6
      7 #include <new>
      8
      9 using std::bad_alloc;
     10
     11 //========================================================================================================================
     12 template < class DataType >
     13 class xCParentsOperation
     14 {
     15 public :
     16     inline xCParentsOperation( int p_size );
     17           ~xCParentsOperation( );
     18
     19 protected :
     20     inline void                      NamolaPrintInfo( void );
     21     inline DataType&                 operator[] ( int p_index );
     22     const xCParentsOperation< DataType >& operator= ( const xCParentsOperation< DataType >& Right );
     23
     24 private :
     25     DataType* m_Alloc;
     26     int       m_Size;
     27 };
     28 //========================================================================================================================
     29
     30 //------------------------------------------------------------------------------------------------------------------------
     31 template < class DataType >
     32 inline
     33 xCParentsOperation< DataType >::xCParentsOperation( int p_size )
     34     :m_Alloc( 0 )
     35 //------------------------------------------------------------------------------------------------------------------------
     36 {
     37     try
     38     {
     39         m_Alloc = new DataType[ p_size ];
     40     }
     41     catch( bad_alloc &memoryAllocationException )
     42     {
     43         cout << "메모리 할당 실패 : "
     44              << memoryAllocationException.what() << endl;
     45     }
     46
     47     m_Size  = p_size;
     48 }
     49
     50 //------------------------------------------------------------------------------------------------------------------------
     51 template < class DataType >
     52 xCParentsOperation< DataType >::~xCParentsOperation()
     53 //------------------------------------------------------------------------------------------------------------------------
     54 {
     55     if ( m_Alloc ) delete[] m_Alloc;
     56     m_Alloc = 0;
     57 }
     58
     59 //------------------------------------------------------------------------------------------------------------------------
     60 template < class DataType >
     61 inline
     62 DataType& xCParentsOperation< DataType >::operator[] ( int p_index )
     63 //------------------------------------------------------------------------------------------------------------------------
     64 {
     65     return m_Alloc[ p_index ];
     66 }
     67
     68 //------------------------------------------------------------------------------------------------------------------------
     69 template < class DataType >
     70 const xCParentsOperation< DataType >& xCParentsOperation< DataType >::operator= ( const xCParentsOperation< DataType >& Right )
     71 //------------------------------------------------------------------------------------------------------------------------
     72 {
     73     if ( &Right != this )
     74     {
     75         if ( m_Size != Right.m_Size )
     76         {
     77             delete [] m_Alloc;
     78             m_Size = Right.m_Size;
     79
     80             try
     81             {
     82                 m_Alloc = new DataType[ m_Size ];
     83             }
     84             catch( bad_alloc &memoryAllocationException )
     85             {
     86                 cout << "메모리 할당 실패 : "
     87                      << memoryAllocationException.what() << endl;
     88             }
     89
     90             for ( int i = 0; i < m_Size; ++i )
     91                 m_Alloc[ i ] = Right.m_Alloc[ i ];
     92
     93         }
     94     }
     95
     96     return *this;
     97 }
     98
     99 //------------------------------------------------------------------------------------------------------------------------
    100 template < class DataType >
    101 inline
    102 void xCParentsOperation< DataType >::NamolaPrintInfo( void )
    103 //------------------------------------------------------------------------------------------------------------------------
    104 {
    105     printf( "부모 멤버 함수 호출\n" );
    106 }
    107
    108 //========================================================================================================================
    109 template < class DataType >
    110 class xCChildOperation : public xCParentsOperation< DataType >
    111 {
    112 public :
    113     inline xCChildOperation( int Size = 1 );
    114     ~xCChildOperation();
    115
    116     inline DataType& operator[] ( int p_index );
    117     inline void ParentsCall( xCChildOperation< DataType >& a1, xCChildOperation< DataType >& a2 );
    118
    119 private :
    120     DataType* m_ChildAlloc;
    121     int       m_ChildSize;
    122 };
    123 //========================================================================================================================
    124
    125 //------------------------------------------------------------------------------------------------------------------------
    126 template < class DataType >
    127 inline
    128 xCChildOperation< DataType >::xCChildOperation( int Size )
    129     :xCParentsOperation< DataType >( Size ), m_ChildAlloc( 0 )
    130 //------------------------------------------------------------------------------------------------------------------------
    131 {
    132     try
    133     {
    134         m_ChildAlloc = new DataType[ Size ];
    135     }
    136     catch( bad_alloc &memoryAllocationException )
    137     {
    138         cout << "메모리 할당 실패 : "
    139              << memoryAllocationException.what() << endl;
    140     }
    141
    142
    143     m_ChildSize = Size;
    144 }
    145
    146 //------------------------------------------------------------------------------------------------------------------------
    147 template < class DataType >
    148 xCChildOperation< DataType >::~xCChildOperation()
    149 //------------------------------------------------------------------------------------------------------------------------
    150 {
    151     if ( m_ChildAlloc ) delete[] m_ChildAlloc;
    152     m_ChildAlloc = 0;
    153 }
    154
    155 //------------------------------------------------------------------------------------------------------------------------
    156 template < class DataType >
    157 inline
    158 void xCChildOperation< DataType >::ParentsCall( xCChildOperation< DataType >& a1, xCChildOperation< DataType >& a2 )
    159 //------------------------------------------------------------------------------------------------------------------------
    160 {
    161     a1.NamolaPrintInfo();
    162     a1[ 0 ] = 1;
    163     int i = a1[ 0 ];
    164     printf( "a1[ 0 ] => %d\n", i );
    165     a2.NamolaPrintInfo();
    166     a2[ 0 ] = 2;
    167     i = a2[ 0 ];
    168     printf( "a2[ 0 ] => %d\n", i );
    169
    170     a1 = a2;
    171     printf( "a1 = a2 : %d\n", a1[ 0 ] );
    172 }
    173
    174 //------------------------------------------------------------------------------------------------------------------------
    175 template < class DataType >
    176 inline
    177 DataType& xCChildOperation< DataType >::operator[] ( int p_index )
    178 //------------------------------------------------------------------------------------------------------------------------
    179 {
    180     return m_ChildAlloc[ p_index ];
    181 }
    182
    183 int main ( void )
    184 {
    185     xCChildOperation< int > a1( 10 ), a2( 10 );
    186     a1.ParentsCall( a1, a2 );
    187
    188     return 0;
    189 }

조금 수정 하였습니다.
operator= 연산자가 상속이 가능한 이유는 무엇인가요?
theuhm의 이미지

C++표준안에 다음과 같이 명시되어 있군요.

Quote:

13.5.3 Assignment
1. An assignment operator shall be implemented by
no n-static member function with exactly one
parameter. Because a copy assignment operator
operator= is implicitly declared for a class if not declared
by the user (12.8), a base class assignment operator is
always hidden by the copy assignment operator in
derived class.

2. Any assignemtn operator, even the copy assignment
operator, can be virtual. [Note: for a derived class D
with a base class B for which a virutal copy assignment
has been declared, the copy assignment operator in D
does not override B's virtual copy assignment operator.


부모 클래스의 대입 연산자는 항상 자식 클래스의 대입 연산자에
의해서 가려진다, 라고 명시되어 있군요 :) 버추얼 연산자라 해도
오버라이딩 되지는 않는다고 합니다.

..

nayana의 이미지

감사합니다. 제가 알기로는 모든 연산자는 오버라이딩이 안된다는것으로 알고 있습니다. 일반 함수는 부모클래스에서 virtual void a(); 자식 클래서에서 virtual void a(): 할수 있지만 즉 재정의가 가능하지만 operator연산자는 재정의가 불가능한것으로 알고 있습니다.
위의 소수 경우는 재정의도 아니고 말 그대로 상속을 받아서 쓰는것인데...문법책에 보게 되면 생성자, 소멸자, friend, operator는 상속이 불가능하다고 나오는데...위의 소수 같은 경우는 현재 상속이
가능합니다. 그래서 마니 당황스럽습니다.
아니면 제 소스가 잘못된 경우인데!!!

doldori의 이미지

nayana wrote:
제가 알기로는 모든 연산자는 오버라이딩이 안된다는것으로 알고 있습니다.

그렇지 않습니다. 오버로딩이 허용되는 연산자 중에서 대입연산자를 제외한
모든 연산자는 오버라이딩이 가능합니다.

xCChildOperation::operator=을 명시적으로 선언하지 않았으므로 컴파일러가
대신 만들어 주는데 그 내용은 대략 다음과 같습니다.

template < class DataType > 
xCChildOperation< DataType >&
    xCChildOperation< DataType >::operator=
    ( const xCChildOperation< DataType >& Right ) 
{
     xCParentsOperation<DataType>::operator=(Right);  //  (1)
     m_ChildAlloc = Right.m_ChildAlloc;
     m_ChildSize = Right.m_ChildSize;
     return *this;
}

170 라인의 a1 = a2 에서 호출하는 함수가 xCParentOperation::operator=라고
생각하시나 본데 그렇지 않습니다. 컴파일러가 만든 xCChildOperation::operator=를
호출합니다. (따라서 xCChildOperation의 경우 대입연산자를 명시적으로 정의하지
않으면 문제가 발생한다는 것을 눈치 채실 수 있겠지요? 복사생성자도요. 이외에도
군데군데 이상한 곳이 눈에 띄지만 지금 논의와는 관계가 없으니 언급하지 않겠습니다.)
nayana의 이미지

답변에 감사드립니다. 님의 말씀대로면 디버깅을 해보면 부모클래스의 operator= 연산자를 호출하던데...이거는 무엇인지요?
그리고
군데군데 이상한 곳이 눈에 띄지만 지금 논의와는 관계가 없으니 언급하지 않겠습니다
이상한 부분은 어디인지요? 알려주시면 감사하겠습니다.

doldori의 이미지

nayana wrote:
님의 말씀대로면 디버깅을 해보면 부모클래스의 operator= 연산자를 호출하던데...이거는 무엇인지요?

바로 위의 소스의 (1)로 표시한 곳에서 호출하는 것입니다.

nayana wrote:
이상한 부분은 어디인지요? 알려주시면 감사하겠습니다.

17 ~xCParentsOperation( );
부모 클래스로 사용되는 클래스의 소멸자는 가상으로 선언하는 것이 보통입니다.

22 const xCParentsOperation< DataType >& operator= ( const xCParentsOperation< DataType >& Right ); 보통 operator=의 반환형은 const가 아닙니다.

struct S;
int i, j, k;
(i = j) = k;    // ok
S s1, s2, s3;
(s1 = s2) = s3; // error with const version
이렇게 쓸 일은 거의 없겠지만 내장형과 최대한 같은 식으로 동작하도록 하기 위해서입니다.

try-catch 구문 메모리 할당에 실패하면 생성자 내에서 예외를 받도록 되어 있는데 이것은 이상합니다. m_Alloc은 초기화되지 않은 상태에서 m_Size만 초기화하고 생성이 완료되니까요. 제 말뜻은 생성자에서 throw bad_alloc() 같은 식으로 예외를 던지고 생성자를 호출하는 main 함수에서 예외를 받아 적절하게 처리하라는 뜻이었습니다.

지금은 자식 클래스에서도 new를 쓰니 operator=를 따로 정의할 필요가 있고
부모/자식 클래스 모두 복사생성자도 정의해야 하겠습니다.

mr.lee의 이미지

Quote:

코드:
class B
{
public:
void f();
B& operator=(const B&);
};

class D : public B { };

D d1, d2;
d1.f(); // (1)
d1 = d2; // (2)

이때 (1)에서 호출하는 함수는 B::f()입니다. 상속받았으므로 당연한 얘기죠.
그러나 (2)에서는 그렇지 않습니다. D::operator=()가 호출됩니다. 이 함수는
컴파일러가 대신 만들어 주기 때문에 눈에 보이지 않을 뿐 B::operator=()와는
다른 함수입니다. 이것이 상속받은 멤버와의 차이입니다.

제가 위에 올린 댓글에 대해서 설명을 좀 부탁합니다. 전 잘됩니다만.. 지금 제 플젝에서 좀 중요한 이슈라서 명확히 짚어야 하거든요

atie의 이미지

잠시 끼어들면, assignment operator에 의해 overwritten되는 object의 복사는 C++ 컴파일러가 멤버-wise constructor와 assignment operator를 생성을 합니다. (모든 경우에 그렇다는 것은 아니고, 클래스를 작성할 때, 별도의 지정이 없으면 그렇다는 이야기 입니다.)
그런데, 이렇게 컴파일러가 생성한 것은 경우에 따라 부적절할 수 있다는 것이 문제여서 주의를 기울어야 합니다.

또 한가지, 자바에서는 위의 경우 (컴파일러가 생성을 하는 경우)가 원천적으로 봉쇄가 되어 있기에 cloneable이나 clone 멤버를 만들게 되는데 이것을 생각해 보면 위의 답도 유추가 되리라 생각됩니다.(변환기를 만드신다고 하니 이해를 하시리라 생각합니다.)

----
I paint objects as I think them, not as I see them.
atie's minipage

doldori의 이미지

nayana님께 드린 답변으로 다 설명이 됐다고 생각합니다만.

class A { 
    public: 
        A& operator=(const A&) { cout << "A" << endl; } 
}; 

class B : public A { }; 

B 클래스에 컴파일러가 만들어주는 코드를 추가하면 대략 다음처럼 됩니다.
class B : public A
{
public:
    B& operator=(const B& b)
    {
        A::operator=(b);
        return *this;
    }
}; 

따라서
B c, d;
c = d;
를 하게 되면 A::operator=가 바로 호출되는 것이 아니라, B::operator=가 호출되고
그 안에서 A::operator=가 호출되는 것이지요. 이제 실행 결과가 왜 그렇게 되는지
이해하셨으리라 믿습니다.
mr.lee의 이미지

좋은 설명들 감사합니다.

nayana의 이미지

설명 감사합니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.