Link to home
Start Free TrialLog in
Avatar of perlperl
perlperl

asked on

nested class

class A {
   private:
        std::set <uint32_t> ids;
   friend class B; 

   class B {
        public: 
             B(uint32_t in) : num (in) {
                 ids.insert(num);  // compiler error here
             }
             ~B() {
                 ids.erase(num);   // compier error here too. 
               }
         private: 
             uint32_t num; 
    };
};

main() { 
   A onj;
   { 
      

   }
}

Open in new window


Compiler is failing with
 error: invalid use of nonstatic data member
Avatar of perlperl
perlperl

ASKER

I think so I got it

class A {
   private:
        std::set <uint32_t> ids;
   friend class B; 

   class B {
        public: 
             B(A& a, uint32_t in) : base(a), num (in) {
                 base.ids.insert(num);  
             }
             ~B() {
                 base.ids.erase(num);  
               }
         private: 
             A& base;
             uint32_t num; 
    };
};

main() { 
   A onj;
   { 
      

   }
}

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of jkr
jkr
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
MSDN has a nice caveat on this (http://msdn.microsoft.com/en-US/library/x23h0937%28v=VS.80%29.aspx) as a 'roundup':

Nested classes declare only types within class scope. They do not cause contained objects of the nested class to be created. The preceding example declares two nested classes but does not declare any objects of these class types.
Ooops, missed your above comment... Yes, that would work and eliminates the problem I mentioned above: " you would need to know to which instance of 'A' you are referring to."
Oh, just one thing about terminology - instead of using

A& base;

Open in new window


in 'B', you'd better call that

A& outer;

Open in new window


And there still is one issue - this way, you can't have a 'B' be a member of 'A', since these would use the default constructor.
But I don't have a default constructor defined for B so it will never enter anything into the set "ids"
Also I do not have a member of B inside A.

I always create an object of B inside one of the method of A. so this guarantees when I create object of B, it will insert into set and when the method exists, element is erased from set
Well, then it's OK. I just wanted to point that out. And even if you needed a member 'B', you could just provide a 'SetOuter()'/'SetInstanceOfA()' accessor.
a std::set would ignore duplicate keys. so if you have two instances of B with same number and  same base A,  deleting one of them would  erase the number for the second as well.

of course you could use the set to generate only unique numbers for B objects. but, if i understand the concept correctly, and as long as you don't store B pointers somewhere, there are only a few  B objects in the current scope, and i wonder why you need a set of their numbers, if so. on the other hand if you store pointers to B somewhere, it would be better to have a map with number key and B pointer as data instead of a set.

Sara