Thread: Upcast problem of an array

  1. #1
    Registered User
    Join Date
    Sep 2005
    Posts
    3

    Upcast problem of an array

    My program allocated an array of class "CB" (CB* pB = new CB[3], and then, "pB" will be post to a method as a parameter (void test( CA* pA, int num)). CA is the superclass of CB. So, in function "test", pA will be used as an array for CA. In this case, how can I upcast successfully? The following program would only upcast the first element of pB to class "CA", from the 2nd element of array, I got the wrong result... Is there anyone could help me? thx!!!!

    Code:
    class CA {
    public:
    void setA( int num ) { a = num; }
    void doSth() {
    printf( "A is: %d\n", a );
    }
    CA() { a = 0; };
    private:
    int a;
    };
    
    class CB : public CA {
    public:
    void setB( int num ) { b = num; }
    void doSth() {
    printf( "B is: %d\n", b );
    }
    CB() { b = 0; };
    private:
    int b;
    };
    
    void test( CA* pA, int num )
    {
    for( int i=0; i<num; i++ ) {
    pA[i].doSth();
    }
    }
    
    int main(int argc, char* argv[])
    {
    CB* pB = new CB[3];
    pB[0].setA(1);
    pB[1].setA(2);
    pB[2].setA(3);
    
    test( dynamic_cast<CA*> (pB), 3 );
    
    int nTest;
    nTest = getchar();
    return 0;
    }

  2. #2
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793
    C++ has a serious gotcha with this

    http://geneura.ugr.es/~jmerelo/c++-f...heritance.html

    Scroll down to "[21.4] Is an array of Derived a kind-of array of Base?"

  3. #3
    Registered User
    Join Date
    Sep 2005
    Posts
    3
    Thx for ur information!!

    Actually, I got a funny way to solve this problem from the other forum :-)
    Code:
    class CA {
    public:
    	void setA( int num ) { a = num; }
    	void doSth() {
    	printf( "A is: %d\n", a );
    	}
    	CA() { a = 0; };
    private:
    	int a;
    };
    
    class CB : public CA {
    public:
    	void setB( int num ) { b = num; }
    	void doSth() {
    	printf( "B is: %d\n", b );
    	}
    	CB() { b = 0; };
    private:
    	int b;
    };
    
    void test( C.......... pA, int num )
    {
    	for( int i=0; i<num; i++ ) {
    		pA[i]->doSth();
    	}
    }
    
    int main(int argc, char* argv[])
    {
    	C.......... ppB = new CA*[3];
    	for (int i = 0;i<3;i++)
    		ppB[i] = new CB();
    	ppB[0]->setA(1);
    	ppB[1]->setA(2);
    	ppB[2]->setA(3);
    
    	test( ppB, 3 );
    
    	int nTest;
    	nTest = getchar();
    	return 0;
    }

  4. #4
    Registered User
    Join Date
    Jan 2003
    Posts
    648
    That would only be legal if what you meant by C...... is CA **. If you meant C..... to mean CB **, then that would be illegal. That FAQ item is a bit hard to understand; but basically, take this situation:

    You have an array of apples and some function casts it up to an array of fruits. That function adds an orange to that array of fruits (legal, an orange is a fruit). However, it's actually illegal because that array of fruits is actually an array of apples and you essentially have an orange pretending to be an apple. Bad.

  5. #5
    Registered User
    Join Date
    Sep 2005
    Posts
    3
    Yeah, it's the reason why I called it a "funny way" - It's not a real solution for the problem

    Anyway, I'd already gave up and began to change the function "test" - previously, I didn't want to touch it.

    Miss Java so much now... Classes in Java could upcast/downcast easily

  6. #6
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    It is easy in C++ as well. You must hold pointers in your array (much like in Java where each variable is actually a reference). I assume C.......... is supposed to be CA ** but got caught by the filters. As Speedy5 said the idea is correct, it is not a "funny way" at all.

    The key is to keep pointers or references to your object instances so that the dynamic type (CB in this case) is maintained while the static type of the pointer can generically refer to the base class.

    The test function must be changed because there is no way it can work with its original signature.
    Last edited by Daved; 09-27-2005 at 10:06 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Array problem
    By TomBoyRacer in forum C++ Programming
    Replies: 3
    Last Post: 04-08-2007, 11:35 AM
  2. Replies: 6
    Last Post: 02-15-2005, 11:20 PM
  3. Merge sort please
    By vasanth in forum C Programming
    Replies: 2
    Last Post: 11-09-2003, 12:09 PM
  4. Need desperate help with two dimensional array problem
    By webvigator2k in forum C++ Programming
    Replies: 4
    Last Post: 05-10-2003, 02:28 PM
  5. From stream/file to a string array problem
    By dradsws in forum C Programming
    Replies: 2
    Last Post: 10-01-2001, 06:24 PM