00001 /* 00002 Copyright (c) 2000-2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. 00003 00004 Redistribution and use in source and binary forms, with or without 00005 modification, are permitted provided that the following conditions are met: 00006 00007 * Redistributions of source code must retain the above copyright notice, this 00008 � list of conditions and the following disclaimer. 00009 * Redistributions in binary form must reproduce the above copyright notice, 00010 � this list of conditions and the following disclaimer in the documentation 00011 � and/or other materials provided with the distribution. 00012 * Neither the name of Nokia Corporation nor the names of its contributors 00013 � may be used to endorse or promote products derived from this software 00014 � without specific prior written permission. 00015 00016 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00017 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00018 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00019 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00020 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00021 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00022 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00023 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00024 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00025 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00026 00027 Description:� 00028 */ 00029 00030 00031 #include "CommonFramework.h" 00032 00033 // start of real example 00034 00035 // #include specific files 00036 00037 // class with single-phase construction, NewL and NewLC 00038 00039 class COnePhaser : public CBase { 00040 public: // data 00041 TInt iInt1; // one integer 00042 TInt iInt2; // another integer 00043 public: // functions 00044 // construct/destruct 00045 static COnePhaser* NewL() 00046 { // construct and leave if error 00047 return new (ELeave) COnePhaser; // new COnePhaser, C++ constructor 00048 }; 00049 static COnePhaser* NewLC() 00050 { // construct, leave if error, else push to clean-up stack 00051 COnePhaser* self=COnePhaser::NewL(); // construct 00052 CleanupStack::PushL(self); // push to clean-up stack 00053 return self; // and return new object 00054 }; 00055 // other functions 00056 void Print() 00057 { 00058 _LIT(KFormat1,"COnePhaser {TInt %d, TInt %d}"); 00059 console->Printf(KFormat1, iInt1, iInt2); 00060 } 00061 protected: // functions 00062 // construct 00063 COnePhaser() 00064 { // standard C++ constructor, because it cannot leave 00065 iInt1=3; // set first int to 3 00066 // iInt2=0; // unnecessary 00067 } 00068 }; 00069 00070 // class with two-phase construction 00071 00072 class CTwoPhaser : public CBase { 00073 public: // data 00074 TInt iInt1; // one integer 00075 TInt iInt2; // another integer 00076 RTimer iTimer; // a resource 00077 COnePhaser* iOnePhaser; // another CBase object 00078 public: // functions 00079 // construct/destruct 00080 static CTwoPhaser* NewLC(TInt aInt1) 00081 { // construct and leave on the clean-up stack 00082 CTwoPhaser* self=new (ELeave) CTwoPhaser; // new CTwoPhaser, initialized to binary zeroes 00083 CleanupStack::PushL(self); // push to clean-up stack 00084 self->ConstructL(aInt1); // construct 00085 return self; // return new object 00086 }; 00087 static CTwoPhaser* NewL(TInt aInt1) 00088 { // construct and don't leave on clean-up stack 00089 CTwoPhaser* self=CTwoPhaser::NewLC(aInt1); // construct and leave on clean-up stack 00090 CleanupStack::Pop(); // pop from clean-up stack 00091 return self; // return new object 00092 }; 00093 virtual ~CTwoPhaser() 00094 { 00095 delete iOnePhaser; // just destroy anything we point to 00096 iTimer.Close(); // close timer 00097 } 00098 // other functions 00099 void Print() 00100 { 00101 _LIT(KFormat2,"CTwoPhaser {TInt %d, TInt %d, RTimer, "); 00102 console->Printf(KFormat2, iInt1, iInt2); 00103 iOnePhaser->Print(); 00104 _LIT(KtxtCloseCurly,"}"); 00105 console->Printf(KtxtCloseCurly); 00106 } 00107 protected: // functions 00108 // construct support 00109 void ConstructL(TInt aInt1) 00110 { // do the work involved in construction 00111 iInt1=aInt1; // assign iInt1 from argument 00112 User::LeaveIfError(iTimer.CreateLocal()); // initialize timer 00113 iOnePhaser=COnePhaser::NewL(); // make a new one-phaser 00114 } 00115 }; 00116 00117 // abstract class derived from CBase 00118 00119 class CAbstract : public CBase 00120 { 00121 public: // data 00122 CTwoPhaser* iTwoPhaser; // a contained object 00123 public: // functions 00124 void SomeFunction(TInt aInt) 00125 { // request some function 00126 _LIT(KTxtbeginSomeFunction,"beginning to do SomeFunction()\n"); 00127 console->Printf(KTxtbeginSomeFunction); 00128 DoSomeFunction(aInt); // invoke virtual function 00129 _LIT(KTxtfinishSomeFunction,"finished doing SomeFunction()\n"); 00130 console->Printf(KTxtfinishSomeFunction); 00131 } 00132 virtual ~CAbstract() 00133 { 00134 delete iTwoPhaser; 00135 } 00136 protected: 00137 virtual void DoSomeFunction(TInt aInt) const =0; 00138 // implement heart of some function, in derived class 00139 void ConstructL(TInt aInt) 00140 { // second phase of constructor 00141 iTwoPhaser=CTwoPhaser::NewL(aInt); 00142 // construct embedded object 00143 } 00144 }; 00145 00146 // class derived from above 00147 00148 class CConcrete : public CAbstract 00149 { 00150 public: // data 00151 COnePhaser* iOnePhaser; // some extra data 00152 public: // functions 00153 // construct/destruct 00154 static CConcrete* NewLC(TInt aInt) 00155 { // construct and leave on the clean-up stack 00156 CConcrete* self=new (ELeave) CConcrete; // new object, C++ constructor 00157 CleanupStack::PushL(self); // push to clean-up stack 00158 self->ConstructL(aInt); // CBase constructor 00159 return self; // return new object 00160 }; 00161 static CConcrete* NewL(TInt aInt) 00162 { // construct and don't leave on clean-up stack 00163 CConcrete* self=CConcrete::NewLC(aInt); // construct and leave on clean-up stack 00164 CleanupStack::Pop(); // pop from clean-up stack 00165 return self; // return new object 00166 }; 00167 virtual ~CConcrete() 00168 { 00169 delete iOnePhaser; // destroy member 00170 } 00171 // protocol 00172 virtual void DoSomeFunction(TInt aInt) const 00173 { // implementation of base class's pure-virtual function 00174 _LIT(KFormat3,"CConcrete::DoSomething(%d)\n"); 00175 console->Printf(KFormat3, aInt); 00176 } 00177 protected: 00178 // construct/destruct 00179 void ConstructL(TInt aInt) 00180 { // second phase of construction 00181 CAbstract::ConstructL(aInt); // base class constructor 00182 iOnePhaser=COnePhaser::NewL(); // contained member constructor 00183 } 00184 }; 00185 00186 // do the example 00187 LOCAL_C void doExampleL() 00188 { 00189 // two-phase object 00190 CTwoPhaser* twoPhaser=CTwoPhaser::NewLC(5); 00191 // new two-phase object 00192 twoPhaser->Print(); // print it 00193 _LIT(KTxtNewLine,"\n"); 00194 console->Printf(KTxtNewLine); // with trailing new-line 00195 CleanupStack::PopAndDestroy(); // two-phase object 00196 // concrete instance of an abstract class 00197 CAbstract* abstract=CConcrete::NewLC(9); 00198 // new concrete object, but refer to it with abstract pointer 00199 abstract->SomeFunction(11); // do something with it 00200 CleanupStack::PopAndDestroy(); // abstract object 00201 }