CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 19
  1. #1
    Join Date
    Dec 2003
    Posts
    30

    STL and pointer/reference question

    Hi all,

    Im rather new to C++ (I´m changing from Java to C++), so please bear with me.
    I have a question about STL and returning a vector array
    from a static method.

    How do I do it correctly, so that the function contructs
    a vector that can be returned to the caller. I know if I
    create a local object from a class and return it`s reference, it will point to null (if I´m rigth) after the
    function call. So the object should be created with the new
    operator. But how do I do it with template call??
    I just get errors when I try to compile.

    It should go something like this(please, do correct my syntax, pointers and references are used very wrong, I think):

    static &vector<MyClass> loadFromFile()
    {
    vector<MyClass> *data = NULL;
    try
    {
    // load from file and populate the vector
    }
    catch(...)
    { }

    return &data;
    }

    help apprecitaed!

    -mark


    ps. could somebody tell me where to fing a decent
    standard C++ API (yes, I`m migrating from Java to C++). All I have found are rather hard to use / read or incomplete.

    Thank you.

  2. #2
    Join Date
    Feb 2002
    Posts
    5,757
    One solution is to encapsulate the STL container within a structure. Create the object on the heap and pass its pointer.

    Kuphryn

  3. #3
    Join Date
    Apr 1999
    Posts
    27,449

    Re: STL and pointer/reference question

    Originally posted by halmark6Z
    How do I do it correctly, so that the function contructs
    a vector that can be returned to the caller.
    A vector has proper copy semantics, so there is no need to be using references or pointers.
    Code:
    #include <vector>
    class MyClass
    {
    };
    
    static std::vector<MyClass> loadFromFile(); // if you really need a static function
    
    std::vector<MyClass> loadFromFile()
    {
       std::vector<MyClass> data;
       try
      {
            // load from file and populate the vector
      }
      catch(...) 
      { }
      return data;
    }
    
    int main()
    {
       std::vector<MyClass> M;
       M = loadFromFile();
    }
    The code is much more easier than you thought it would be.
    I know if I create a local object from a class and return it`s reference,
    Return it by value (as my code does above), not by reference.

    it will point to null (if I´m rigth) after the
    function call. So the object should be created with the new
    operator.
    You're right, you do come a Java background, since you do not need to create an object with "new" in C++.
    It should go something like this(please, do correct my syntax, pointers and references are used very wrong, I think):
    Again, no need to use pointers or references.
    ps. could somebody tell me where to fing a decent
    standard C++ API (yes, I`m migrating from Java to C++). All I have found are rather hard to use / read or incomplete.
    Get "Accelerated C++" by Koenig & Moo.

    Regards,

    Paul McKenzie

  4. #4
    Join Date
    Dec 2003
    Posts
    30
    Thanks for your replies. Helped a lot, really!

    But, could you explain little more futher this:

    A vector has proper copy semantics, so there is no need to be using references or pointers.
    How it prevents a local copy from going out of scope?

    again, many thanks!

  5. #5
    Join Date
    Nov 2002
    Location
    Los Angeles, California
    Posts
    3,863
    The local data does go out of scope, but the function returns a copy of the local data. The copy can be assigned to something outside the function scope.

    By the way, another option is to pass the vector into the function
    as a parameter.
    PHP Code:
    #include <vector>
    class MyClass
    {
    };

    static 
    void ChangeVector(std::vector<MyClass>& my_class_vect); // if you really need a static function

    void ChangeVector(std::vector<MyClass>& my_class_vect )
    {
       
    //the vector is a changing
    }

    int main()
    {
       
    std::vector<MyClassM;
       
    ChangeVector(M);

    Wakeup in the morning and kick the day in the teeth!! Or something like that.

    "i don't want to write leak free code or most efficient code, like others traditional (so called expert) coders do."

  6. #6
    Join Date
    Dec 2003
    Posts
    30
    Thanks for your replies. Helped a lot, really!

    But, could you explain little more futher this:

    A vector has proper copy semantics, so there is no need to be using references or pointers.
    How it prevents a local copy from going out of scope?

    again, many thanks!

  7. #7
    Join Date
    Nov 2002
    Location
    Los Angeles, California
    Posts
    3,863
    Originally posted by souldog
    The local data does go out of scope, but the function returns a copy of the local data. The copy can be assigned to something outside the function scope.

    By the way, another option is to pass the vector into the function
    as a parameter.
    PHP Code:
    #include <vector>
    class MyClass
    {
    };

    static 
    void ChangeVector(std::vector<MyClass>& my_class_vect); // if you really need a static function

    void ChangeVector(std::vector<MyClass>& my_class_vect )
    {
       
    //the vector is a changing
    }

    int main()
    {
       
    std::vector<MyClassM;
       
    ChangeVector(M);

    Wakeup in the morning and kick the day in the teeth!! Or something like that.

    "i don't want to write leak free code or most efficient code, like others traditional (so called expert) coders do."

  8. #8
    Join Date
    Apr 1999
    Posts
    27,449
    Originally posted by halmark6Z
    Thanks for your replies. Helped a lot, really!

    But, could you explain little more futher this:



    How it prevents a local copy from going out of scope?

    again, many thanks!
    Consider the following:
    Code:
    int foo()
    {
       int i = 0;
       return i;
    }
    
    int main()
    {
        int myval = foo();
    }
    Note that the foo() function has created a local int, i, and returns it by value. The main() function calls foo() and assigns it to an int.

    Compare this simple example using int's with the example using std::vector<> -- the only difference is the type returned. That is the beauty of C++. If your class provides a copy constructor and assignment operator, the class acts just like one of the basic types when returning by value. For vector, the assignment operator copies one vector to another, and the copy ctor creates a vector from an existing vector. So when you do a return of std::vector<>, you are invoking the copy constructor.

    So in lay terms, you didn't question whether the local int in the foo()goes out of scope, right? So why question whether the vector goes out of scope? -- it follows the same rules of return by value. Now, if you return a pointer or reference to the local, then scope issues are a concern. My vector code does neither -- it returns by value, just like the int foo() example does.

    The only other concern is if your class does not implement a properly behaved copy constructor and assignment operator (i.e. the class uses the default copy and assignment when it shouldn't be using them, or you just coded user-defined versions of these functions incorrectly), then of course, returning by value still "works", but it will introduce a bug.

    Regards,

    Paul McKenzie

  9. #9
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470
    To add to Paul's reply:

    Java and C# (AFAIK) don't actually copy objects: if you say "a = b" (where a and b have class type), then the object referred to by "a" has its reference count decremented, and the object referred to by "b"has its reference count incremented to reflect that it is now referred to by "a" as well. In C++, the same statement creates two independent copies of the same data - whatever data "a" originally contained is lost (overwritten). No reference counts involved. C++ doesn't do reference counting unless you implement it yourself. This is why copy constructors, copy assignment operators and destructors are so important - C++ makes you do your own resource management. Oh, and I should say that, IMHO although that may seem to be a disadvantage, it actually gives you a lot more flexibility than garbage collection once you're used to it.
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
    --
    Sutter and Alexandrescu, C++ Coding Standards

    Programs must be written for people to read, and only incidentally for machines to execute.

    --
    Harold Abelson and Gerald Jay Sussman

    The cheapest, fastest and most reliable components of a computer system are those that aren't there.
    -- Gordon Bell


  10. #10
    Join Date
    Nov 2003
    Posts
    1,405
    I'm also new to C++ coming from Java.

    One source of confusion is that Java has call by value only. C and Java has call by value only, Fortran has call by reference only, but Pascal and C++ has a mixed calling mechanism.

    When someone from Java says she's passing something by reference she actually means she's passing a reference by value.

    So in this case what the OP, coming from Java, actually asks is how can I create a collection in a function, and then pass it back to the calling function without copying. The reason is efficiency. If you create say 1 million integers in an STL container in a function you don't want it to be copied back to the calling function. What you want back is a pointer (a reference) to the collection.

  11. #11
    Join Date
    Dec 2003
    Location
    Slovenia
    Posts
    4

  12. #12
    Join Date
    Nov 2003
    Location
    Vienna, Austria
    Posts
    212
    Originally posted by _uj
    I'm also new to C++ coming from Java.

    One source of confusion is that Java has call by value only. C and Java has call by value only, Fortran has call by reference only, but Pascal and C++ has a mixed calling mechanism.

    When someone from Java says she's passing something by reference she actually means she's passing a reference by value.
    Actually the only call-by-value behavior in Java is for primitives, everything else is passed by reference (as there are only references in Java).
    C has call by value or by reference (using pointers).
    C++ has call by value or by reference (using either pointers or references).

    If you need the efficiency of not copying the vector, pass one in.
    All the buzzt
    CornedBee

  13. #13
    Join Date
    May 2000
    Location
    KY, USA
    Posts
    18,652
    Originally posted by kuphryn
    One solution is to encapsulate the STL container within a structure. Create the object on the heap and pass its pointer.
    There is neither a sense nor necessity in doing that in this case...

  14. #14
    Join Date
    May 2000
    Location
    KY, USA
    Posts
    18,652
    Originally posted by halmark6Z
    Thanks for your replies. Helped a lot, really!

    But, could you explain little more futher this:



    How it prevents a local copy from going out of scope?

    again, many thanks!
    In addition, you might want to take a look at this introduction to the 'vector' class...

  15. #15
    Join Date
    Nov 2003
    Posts
    1,405
    Originally posted by CornedBee
    Actually the only call-by-value behavior in Java is for primitives, everything else is passed by reference (as there are only references in Java).
    C has call by value or by reference (using pointers).
    C++ has call by value or by reference (using either pointers or references).
    I didn't expect to find this misconception here. The only parameter passing mechanism in Java is by value. Period. Pass by reference was considered error prone and ruled out by the founders of Java. C also has call by value only. Passing a pointer (reference) by value is NOT the same as pass by reference.
    If you need the efficiency of not copying the vector, pass one in.
    That's one possibility. The other one is to create a new vector on the heap in the function and then return a pointer to it.

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured