Thread: Getting information from one class to another

  1. #1
    Registered User
    Join Date
    Jun 2011
    Posts
    5

    Getting information from one class to another

    Here is the situation

    there is

    Code:
    class A{
      bool managment; // this variable is initialized later after construction
    
      struct UserInfo
      {
         std list::groups;
         std list::rights;
      }
    
      struct GroupInfo
      {
        std list::rights;
      }
    
      UserInfo users[];
      std::map<string,GroupInfo> groups;
    }
    Now in case managment is set to true then the way i am suppose to return rights for a single user is to check every group he is a member of and sum up all the rights. In case management is set to false, that means that the rights member of the UserInfo struct has been filled with values, and working with group is redundant.

    My idea was to turn the UserInfo struct into a class and set the rights member to private and expose instead a getRights() method which would decide how to return the rights. My question is how to do that? In this case I need somehow to pass the information about the state of the management variable to the UserInfo class and also a reference to the groups map? What is the most "objective" way to do this?

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Any member function of a class can see any other variable in the class, private or not. getRights() would seem to me to be a member of the A class, which means it would see the managment variable without you doing any work.

  3. #3
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    Quote Originally Posted by farmer View Post
    Here is the situation

    Code:
    class A{
      bool managment; // this variable is initialized later after construction
    
      struct UserInfo
      {
         std list::groups;
         std list::rights;
      }
    
      struct GroupInfo
      {
        std list::rights;
      }
    
      UserInfo users[];
      std::map<string,GroupInfo> groups;
    }
    this is incorrect C++ syntax.

    the correct way to declare a list is:

    Code:
    std::list rights;
    std::list groups;
    etc.

    if you don't want the caller of getRights() to directly modify the contents of the list (it's generally considered good practice not to allow this), you should return a copy of the list. the easiest way to do this is to declare the getRights() function as follows:

    Code:
    std::list getRights();
    std::list's copy constructor and assignment operator will automatically copy the elements properly, assuming the template type is trivially copyable. if a shallow copy is not appropriate, you will need to define a custom copy constructor and assignment operator for your user-defined type.

    a better way might be to pass a std::list to the getRights() function by reference or pointer, and use std::copy or some other method to fill the list. it could avoid an unnecessary additional copy of the data.

  4. #4
    Registered User
    Join Date
    Aug 2003
    Posts
    1,218
    > if you don't want the caller of getRights() to directly modify the contents of the list (it's generally considered good practice not to allow this), you should return a copy of the list.

    I have to disagree with this one. Any container that can contain an unspecified (but possibly) large amount of objects (such as strings, lists, vectors and so on) I would return a const reference instead.

  5. #5
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    I'd probably make UserInfo and GroupInfo not members of class A for most applications.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  6. #6
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    Quote Originally Posted by Shakti View Post
    I have to disagree with this one. Any container that can contain an unspecified (but possibly) large amount of objects (such as strings, lists, vectors and so on) I would return a const reference instead.
    but a const reference can still be cast to a normal reference. it shouldn't be done, but it can be done, and some people still do it. the safest way is to copy the entire list and return the copy. it's true that a large list of objects could be expensive, in terms of clock cycles, to copy, but it all depends on how much isolation you want between the class code and the calling code.

  7. #7
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by Elkvis View Post
    but a const reference can still be cast to a normal reference. it shouldn't be done, but it can be done, and some people still do it. the safest way is to copy the entire list and return the copy. it's true that a large list of objects could be expensive, in terms of clock cycles, to copy, but it all depends on how much isolation you want between the class code and the calling code.
    This is paranoia gone mad.

    There is no way to accidentally convert a const reference into a non-const reference. If someone does such a thing deliberately, then either they know exactly what they are doing (and you should work with them to provide a valid alternative) or they should wear the consequences of their actions.

    Also, more generally, making a copy of internal data does not guarantee isolation between the class code and calling code. If someone is foolhardy enough to cast away constness of a pointer or reference without a good reason, they are also foolhardy enough to work around the illusion of isolation you have provided by copying data.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  8. #8
    Registered User
    Join Date
    Aug 2003
    Posts
    1,218
    Quote Originally Posted by Elkvis View Post
    but a const reference can still be cast to a normal reference. it shouldn't be done, but it can be done, and some people still do it. the safest way is to copy the entire list and return the copy. it's true that a large list of objects could be expensive, in terms of clock cycles, to copy, but it all depends on how much isolation you want between the class code and the calling code.
    Absurd! Design a library under the assumption that people will use it according to the rules you design it under (do not cast away const for instance) and keep to good design practices (yes i consider pass by const reference rather than pass by value a good design practice, so does the author of Effective C++, a widely cited book when it comes to C++ coding practices). Plus the "isolated" data can still be modified (not sure it's even 100% valid C++ code but hey, if the people you design for break the rules of the library why assume they adhere to the C++ standard...):
    Code:
    #include <iostream>
    #include <vector>
    
    class Foo
    {
    private:
    	std::vector<int> veryLongVector;
    public:
    	Foo()
    	{
    		for(int i=0; i<100000; i++)
    			veryLongVector.push_back(i);
    	}
    
    	std::vector<int> getVector() { return veryLongVector; }
    };
    
    int main(int argc, char** argv)
    {
    	Foo f;
    	std::vector<int> *vec = (std::vector<int>*)&f;
    	(*vec)[0] = 2;
    	std::cout << f.getVector()[0] << std::endl;
    }

  9. #9
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    the point I was making (perhaps you missed it) was that to guarantee that the user can't modify your private class data, copying is the only reliable solution. even if they modify the copy, the class data remains unaffected. your example is a worst-case scenario, and while it certainly illustrates a way to get around access levels in classes, it's even more ridiculous than casting away const-ness.

    this is probably a moot point anyway, since the OP indicated that he/she wants to generate the list of rights dynamically based on the list of groups. in this case, a new list of rights is likely to be generated each time getRights() is called anyway.
    Last edited by Elkvis; 06-21-2011 at 09:06 AM.

  10. #10
    Registered User
    Join Date
    Aug 2003
    Posts
    1,218
    And I am saying you can't guarantee this so why even bother. Do things right (for example do not invoke copy contructor unnessecary, especially for large data-structures) and tell the people who use the library wrong to bugger off. Really, everything else is just poor design and creates badly written libraries. And yes, I agree my example is ridiculous but as grumpy said: either the person casting away const knows what he is doing (which is fine) or he can only blame any problems on his own coding (also fine) so why delibirately write inferior code?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 1
    Last Post: 10-12-2009, 08:22 AM
  2. Getting Information
    By Dark_Phoenix in forum Game Programming
    Replies: 3
    Last Post: 11-09-2006, 02:04 AM
  3. Template <class T1, class T2, class T3> error LNK2019
    By JonAntoine in forum C++ Programming
    Replies: 9
    Last Post: 10-11-2004, 12:25 PM
  4. any information on GUI's will help
    By rxg00u in forum C++ Programming
    Replies: 1
    Last Post: 04-17-2002, 10:29 AM
  5. More C information
    By bean583 in forum C Programming
    Replies: 4
    Last Post: 03-25-2002, 01:37 PM