April 19, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Discovering C++ Idioms in BREW, Page 2

  • May 19, 2004
  • By Radu Braniste, Radu Braniste
  • Send Email »
  • More Articles »

A Singleton should not be directly instantiated (that's why the private constructor) and obviously getInstance() returns the same instance. Let's see how this translates in BREW. Singleton has a unique instance, kept by CPPApp (b_). To access it, Singleton is a friend of CPPApp. On the other hand, the creation of b_ has to be done by CPPApp (in OnAppInitData()) and has to be inhibited at compile time in other contexts (private constructor). This implies that CPPApp has to be a friend of Singleton. An example of using Singleton is presented in test1().

It was mentioned before that simply using CPPApp::sharedValue might create some discomfort for the user. There are some problems with this design:

  • A proliferation of public variables in CPPApp
  • Class Test has no real variable sharedValue; it has to create a link between CPPApp::sharedValue and a member static function to mimic this

A more complex design might alleviate these issues:

class CPPApp : public AEEApplet
{
//....
private:
   friend struct Static;
   void* statics[4];    //simple container
};

struct Static
{
   template <class T>
   static typename T::STATIC_TYPE staticValue()
   {
      CPPApp* c = CPPApp::getInstance();
      return *static_cast<typename T::STATIC_TYPE_PTR>
             (c->statics[T::getUID()]);
   }
    template <class T>
   static void  staticValue(const typename T::STATIC_TYPE t)
   {
      CPPApp* c = CPPApp::getInstance();
      c->statics[T::getUID()] = &t;
    }
};

template <class TP>
struct StaticBase
{
   typedef  TP* STATIC_TYPE_PTR;
   typedef  TP& STATIC_TYPE;
};

Static defines the manipulation pattern and StaticBase is a simple policy class for manipulating types. There is a container of static variables in CPPAppp, Every static variable is uniquely identified by type and an unique ID, a simple int in this case. Let's take, for example, a simple class having two static variables:

struct A  : public Static
{
   StaticA a; 
   StaticB b;
};

This is how the two variables have to be defined to be unique:

struct StaticA : public StaticBase<int>
{
   static size_t getUID()
   {
      return 0;
   }

};

struct StaticB : public StaticBase<int>
{
   static size_t getUID()
   {
      return 1;
   }

};

Now, CPPApp has an automatic way of keeping track of static variables (of course, the array will be replaced by a container in real life). They are strongly typed and user classes now own them:

void test2()
{
   Writer writer;
   int val = 777;
   A::staticValue<StaticA>(val);
   StaticA::STATIC_TYPE i = A::staticValue<StaticA>();
   writer.WriteLine(i);
   i = 2345;
   writer.WriteLine(A::staticValue<StaticA>());
   val = 888;
   A::staticValue<StaticB>(val);
   writer.WriteLine(A::staticValue<StaticB>());
   A::staticValue<StaticB>() = 4567;
   writer.WriteLine(A::staticValue<StaticB>());
}

Resulting Context:

  • We've obtained a behavior consistent with static semantics.
  • But, additional complexity was added.

EverLoad

Problem:

  • How does one use the new/delete operator in BREW?

Forces:

  • BREW doesn't offer a predefined new/delete global operator
  • New/delete operators[7] are of significant importance in BREW (see "Stack Starvation" for a reason why heap allocation is unavoidable)

Solution:

  • Always overload the new/delete operator (always in pairs)
  • Always overload the new[]/delete[] operator
  • The new/delete operator can be overloaded at a global scope or class scope. A good rule of the thumb is to implement a global overload and to use class scope for specific memory allocators[4]
  • Exercise care in switching compilers; there are ANSI/ISO C++ incompatibilities in this area (notably "inline" and operator delete accessibility are pertinent to this topic)[8]

Example:

//global scope
void* operator new(size_t sz);
void operator delete(void *p);

void* operator new[](size_t sz);
void operator delete[](void *p);

class A
{
public:
   static void* operator new(size_t sz);
   static void operator delete(void *p);
//....
}

Related Patterns:

Variable Allocation

What's Next?

The next article will continue this discussion, presenting other idioms.

References

[1] http://brewforums.qualcomm.com

[2] http://brew.qualcomm.com/brew/en/developer/resources/ds/faq.html

[3] http://brew.qualcomm.com/brew/en/developer/resources/ds/okb.html

[4]

[5] GOF. Design Patterns: Elements of Reusable Object-Oriented Software, Addison Wesley. 1994

[6] John M. Vlissides. Pattern Hatching: Design Patterns Applied, Addison Wesley. 1998

[7] For a complete discussion of the new/delete operator, see Scott Meyers. More Effective C++, Addison Wesley. 1996

[8] http://fusshuhn.ourfamily.com/cppincomp.html

Download

Download the accompanying code file here (77 Kb).





Page 2 of 2



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel