Const member initialization list question

Discussion in 'C++' started by Wolfram Humann, Sep 9, 2003.

  1. Hi,

    please don't be too harsh if I made stupid errors creating this simple
    example from my more complex case.

    Suppose I have a class like this:

    class BOOK
    {
    const string title;
    const string author;
    const int pages;
    const double price;

    static map<string, BOOK> MyBooks;

    BOOK(const string& title_, const string& author_,
    const int pages_, const double price_);

    BOOK(const string& title_);

    const BOOK& findByTitle(const string& title);
    }

    I fill the map with books created by the 4-argument constructor. I use
    findByTitle to look up books in the map. My problem is with the
    constructor that takes a title. About the only way to define this
    seems to be:

    BOOK::BOOK(const string& title_)
    : title(title_),
    author(findByTitle(title_).author)
    pages(findByTitle(title_).pages)
    price(findByTitle(title_).price)
    {}

    The problem is that findByTitle is called 3 times. That's not very
    efficient. If my members were non-const I could do

    BOOK::BOOK(const string& title_)
    : title(title_)
    {
    BOOK book = findByTitle(title_);
    author = book.author;
    pages = book.pages;
    price = book.price;
    }

    But since my books don't have a habit of suddenly changing their
    author, I think those members *should* be const. Any elegant
    solutions?

    Thanks,
    Wolfram
     
    Wolfram Humann, Sep 9, 2003
    #1
    1. Advertising

  2. "Wolfram Humann" <> wrote...
    > please don't be too harsh if I made stupid errors creating this simple
    > example from my more complex case.
    >
    > Suppose I have a class like this:
    >
    > class BOOK
    > {
    > const string title;
    > const string author;
    > const int pages;
    > const double price;


    Should price really be 'const'? Never mind...

    >
    > static map<string, BOOK> MyBooks;


    public:

    >
    > BOOK(const string& title_, const string& author_,
    > const int pages_, const double price_);
    >
    > BOOK(const string& title_);
    >
    > const BOOK& findByTitle(const string& title);


    This should probably be 'static'.

    > }

    ;

    I hope those three suggestions are not an indicator of my being harsh.

    >
    > I fill the map with books created by the 4-argument constructor. I use
    > findByTitle to look up books in the map. My problem is with the
    > constructor that takes a title. About the only way to define this
    > seems to be:
    >
    > BOOK::BOOK(const string& title_)
    > : title(title_),
    > author(findByTitle(title_).author)
    > pages(findByTitle(title_).pages)
    > price(findByTitle(title_).price)
    > {}
    >
    > The problem is that findByTitle is called 3 times. That's not very
    > efficient. If my members were non-const I could do
    >
    > BOOK::BOOK(const string& title_)
    > : title(title_)
    > {
    > BOOK book = findByTitle(title_);


    BOOK const & book = findByTitle(title_); // more efficient

    > author = book.author;
    > pages = book.pages;
    > price = book.price;
    > }
    >
    > But since my books don't have a habit of suddenly changing their
    > author, I think those members *should* be const. Any elegant
    > solutions?


    You have to answer the question: why do I need to construct another
    object from a single 'title' when I already have one sitting in the
    map<string, BOOK>? As soon as you can answer that, we'll be able to
    give you an elegant solution. Deal?

    Victor
     
    Victor Bazarov, Sep 9, 2003
    #2
    1. Advertising

  3. On Tue, 09 Sep 2003 17:18:57 GMT, Victor Bazarov <>
    wrote:
    >
    > You have to answer the question: why do I need to construct another
    > object from a single 'title' when I already have one sitting in the
    > map<string, BOOK>? As soon as you can answer that, we'll be able to
    > give you an elegant solution. Deal?
    >
    > Victor
    >
    >


    Suppose the user of the class wants to say:
    (assuming the book is already in the map, error otherwise)

    BOOK stroustrup("The C++ Programming Language");
    cout << "Stroustrup has " << stroustrup.pages << " pages" << endl;

    or I have

    LIBRARY::addBook(BOOK book);

    myLibrary.addBook("The C++ Programming Language");

    I already found that here I need a BOOK::BOOK(const char* title_) (with
    char* instead of string) constructor. I think the reason is that otherwise
    I have an implicit conversion chain with two user-defined conversions...?

    Wolfram
     
    Wolfram Humann, Sep 9, 2003
    #3
  4. Wolfram Humann

    Howard Guest

    "Wolfram Humann" <> wrote in message
    news:eek:pru8ttxa11udsjr@netnews...
    > On Tue, 09 Sep 2003 17:18:57 GMT, Victor Bazarov <>
    > wrote:
    > >
    > > You have to answer the question: why do I need to construct another
    > > object from a single 'title' when I already have one sitting in the
    > > map<string, BOOK>? As soon as you can answer that, we'll be able to
    > > give you an elegant solution. Deal?
    > >
    > > Victor
    > >
    > >

    >
    > Suppose the user of the class wants to say:
    > (assuming the book is already in the map, error otherwise)
    >
    > BOOK stroustrup("The C++ Programming Language");
    > cout << "Stroustrup has " << stroustrup.pages << " pages" << endl;
    >
    > or I have
    >
    > LIBRARY::addBook(BOOK book);
    >
    > myLibrary.addBook("The C++ Programming Language");
    >
    > I already found that here I need a BOOK::BOOK(const char* title_) (with
    > char* instead of string) constructor. I think the reason is that otherwise
    > I have an implicit conversion chain with two user-defined conversions...?
    >
    > Wolfram


    It seems to me that addBook (in the second case at least) should do the
    lookup for the book given the title, and error out if it is not found. Then
    it can create a new instance (or copy-create it, or use a reference to the
    the existing one) based on the one it finds. I'm not sure what you want to
    happen in the first case, since you haven't provided a constructor with no
    parameters, and you're in effect adding an "unknown" book to the library.
    (Also, shouldn't the map be a member of your library class, not a member of
    the book class itself? It seems strange to have a book that has a
    collection of books in it, doesn't it?)

    -Howard
     
    Howard, Sep 9, 2003
    #4
  5. "Wolfram Humann" <> wrote...
    > On Tue, 09 Sep 2003 17:18:57 GMT, Victor Bazarov <>
    > wrote:
    > >
    > > You have to answer the question: why do I need to construct another
    > > object from a single 'title' when I already have one sitting in the
    > > map<string, BOOK>? As soon as you can answer that, we'll be able to
    > > give you an elegant solution. Deal?
    > >
    > > Victor
    > >
    > >

    >
    > Suppose the user of the class wants to say:
    > (assuming the book is already in the map, error otherwise)
    >
    > BOOK stroustrup("The C++ Programming Language");
    > cout << "Stroustrup has " << stroustrup.pages << " pages" << endl;
    >
    > or I have
    >
    > LIBRARY::addBook(BOOK book);
    >
    > myLibrary.addBook("The C++ Programming Language");
    >
    > I already found that here I need a BOOK::BOOK(const char* title_) (with
    > char* instead of string) constructor. I think the reason is that otherwise
    > I have an implicit conversion chain with two user-defined conversions...?


    Doesn't convince me. If you need to find out whether it's there or not,
    use 'find'. If it's there, you will get it, if it's not, you can either
    rely on an exception thrown, or a NULL pointer return value. If you know
    it's not there, construct by giving all needed arguments. If you know
    that it's there, no need to construct another object.

    Victor
     
    Victor Bazarov, Sep 9, 2003
    #5
  6. On Tue, 09 Sep 2003 21:30:03 GMT, Victor Bazarov <>
    wrote:
    >
    > Doesn't convince me. If you need to find out whether it's there or not,
    > use 'find'. If it's there, you will get it, if it's not, you can either
    > rely on an exception thrown, or a NULL pointer return value. If you know
    > it's not there, construct by giving all needed arguments. If you know
    > that it's there, no need to construct another object.
    >
    > Victor
    >


    O.k., I see your point: a constructor should make new objects -- why use
    it when the object is already there.

    Well, for the users of my class these are like new objects as they have
    never seen them. My real case is not about books but an abstraction of
    some electronic hardware. The map is pre-filled with the available modules
    without interaction of the class's user. Maybe that's a weak argument...

    For named objects I think at least a copy-constructor is required, even
    when findByTitle is used instead of a constructor:

    BOOK tolkien( findByTitle("The Hobbit") );

    Also the constructor taking a title is somewhat convenient. Compare:

    cout << BOOK("The Hobbit").author;
    cout << BOOK::findByTitle("The Hobbit").author;
    (Of course .author needs to be replaced by an access function)

    Finally for historical reasons I don't have a choice: I have to provide
    this constructor to be consistent with existing software, even if it's not
    the most logical thing to do.

    My question remains: Can I play any (dirty?) tricks to avoid looking up my
    map three times. (Knowing that this should not really work I tried
    assigning to "this" in the initializer list or calling a copy constructor.
    Of course that failed.)

    If nothing else helps, I would consider making my members non-const or
    putting them all in a struct and initialize that struct in the
    constructors initialization list:

    BOOK::BOOK(const string& title)
    : memberStruct(findByTitle(title).memberStruct)
    {}
     
    Wolfram Humann, Sep 10, 2003
    #6
  7. Wolfram Humann

    Howard Guest

    "Wolfram Humann" <> wrote in message
    news:eek:prvapw1e01udsjr@netnews...
    > On Tue, 09 Sep 2003 21:30:03 GMT, Victor Bazarov <>
    > wrote:
    > >
    > > Doesn't convince me. If you need to find out whether it's there or not,
    > > use 'find'. If it's there, you will get it, if it's not, you can either
    > > rely on an exception thrown, or a NULL pointer return value. If you

    know
    > > it's not there, construct by giving all needed arguments. If you know
    > > that it's there, no need to construct another object.
    > >
    > > Victor
    > >

    >
    > O.k., I see your point: a constructor should make new objects -- why use
    > it when the object is already there.
    >
    > Well, for the users of my class these are like new objects as they have
    > never seen them. My real case is not about books but an abstraction of
    > some electronic hardware. The map is pre-filled with the available modules
    > without interaction of the class's user. Maybe that's a weak argument...
    >


    I'm not even sure what that argument means. What is a "user" of your class?
    Another programmer? An end-user? Or code that makes calls to your class's
    code? I don't see what having "never seen them" means in relation to any of
    those cases. And I still don't see why you need to construct a new instance
    of an object if the object already exists, because all that is doing is
    making a copy of some existing object, and your limited example of using
    that copy does not justify that action.

    Plus, you still haven't explained what a LIBRARY is (nor why your collection
    of BOOKs is contained in a BOOK object instead of a LIBRARY object).

    > For named objects I think at least a copy-constructor is required, even
    > when findByTitle is used instead of a constructor:
    >
    > BOOK tolkien( findByTitle("The Hobbit") );
    >


    I don't understand what you mean when you say "even when findByTitle is used
    instead of a constructor". A copy-constructor takes a const reference to an
    existing object (a BOOK) and creates a new one based on that. It's
    irrelevant how you obtained that reference.

    > Also the constructor taking a title is somewhat convenient. Compare:
    >
    > cout << BOOK("The Hobbit").author;
    > cout << BOOK::findByTitle("The Hobbit").author;


    Is findByTitle a static function??? Why are you specifying
    BOOK::findByTitle, and not something like someBook.findByTitle? This seems
    to point tight back to the use of another class (LIBRARY) to hold the
    collection instead of an individual BOOK.

    > (Of course .author needs to be replaced by an access function)
    >
    > Finally for historical reasons I don't have a choice: I have to provide
    > this constructor to be consistent with existing software, even if it's not
    > the most logical thing to do.
    >


    Well, the mere existence of a constructor that takes just the title instead
    of all its members does not mean that you have to *always* use that
    constructor to use such a book. Assuming that findByTitle returns a
    reference to an existing BOOK object (does it?), then you might want to do
    this:

    BOOK& someOtherBook = someBook.findByTitle("The Hobbit");
    cout << someOtherBook.author << endl;
    cout << someOtherBook.price << endl;

    There's no construction going on here at all, and I only need the
    findByTitle call once.

    (Or if findByTitle returns a pointer, then use a pointer instead of a
    reference...but my point is the same.)

    > My question remains: Can I play any (dirty?) tricks to avoid looking up my
    > map three times. (Knowing that this should not really work I tried
    > assigning to "this" in the initializer list or calling a copy constructor.
    > Of course that failed.)
    >
    > If nothing else helps, I would consider making my members non-const or
    > putting them all in a struct and initialize that struct in the
    > constructors initialization list:
    >
    > BOOK::BOOK(const string& title)
    > : memberStruct(findByTitle(title).memberStruct)
    > {}


    I think your example is just too abstracted to make any sense as it relates
    to the actual problem that you have. But it looks like you've answered your
    own question: if you MUST use this constructor and need to initialize it via
    findByTitle, then using the result of that call to initialize (construct) a
    member struct appears to me to be a good way. But in that case, you'll end
    up doing exactly what we've been suggesting: calling findByTitle to get a
    pointer or reference to an existing BOOK, and passing that pointer or
    reference to a constructor (in this case the constructor of that new struct,
    instead of a new BOOK object).


    Without a more realistic sample of your code and the problem you face,
    (especially showing the context in which you feel the need to use a newly
    constructed object like that instead of a pointer or reference), I doubt we
    can tell you any more than you already know.

    (Sorry if I sound argumentative here....don't mean to.)

    -Howard
     
    Howard, Sep 10, 2003
    #7
  8. Wolfram Humann wrote:
    >

    I still believe you have a design flaw.

    A single book is not a collection of books.
    There should be 2 distinct classes: book - library

    You don't ask a book to find some title. You ask a library
    to look up if there is a book with a specific title.

    Therefore the problem you are now facing simply disappears
    if you correct the design.

    LIBRARY MyLibrary;

    BOOK* pBook = MyLibrary.FindByTitle( "TheHobbit" );

    // if the book is in the library, you now have a pointer to it.

    if( pBook )
    cout << pBook->author;
    else {
    cout << "I don't have that book. Please provide the details to create it\n";
    cin >> author;

    MyLibrary.Add( BOOK( "The Hobbit", author ) );
    }

    --
    Karl Heinz Buchegger
     
    Karl Heinz Buchegger, Sep 11, 2003
    #8
  9. I started writing a reply but can't stay long enough today to finish it.
    Hopefully tomorrow will be less busy. Sorry.

    Wolfram
     
    Wolfram Humann, Sep 11, 2003
    #9
  10. On 10 Sep 2003 20:49:01 GMT, Howard <> wrote:
    >
    > I'm not even sure what that argument means. What is a "user" of your
    > class?
    > Another programmer? An end-user? Or code that makes calls to your
    > class's
    > code? I don't see what having "never seen them" means in relation to
    > any of
    > those cases. And I still don't see why you need to construct a new
    > instance
    > of an object if the object already exists, because all that is doing is
    > making a copy of some existing object, and your limited example of using
    > that copy does not justify that action.


    First of all: I highly appreciate all the efforts (yours and those of
    Victor and Karl Heinz) to help me. This discussion provided me with a
    number of good points to think about in my design. But I think I see that
    my limited example may not be sufficient. And my employer might not
    appreciate if I post the original code ;-). I tried to invent a simple
    case and now we are more into a discussion of that case's design than into
    my original problem. I'll still try to explain what I can. If it's more
    confusing than illuminating, just tell me I'm a hopeless case and abort
    the discussion...

    The "users" are other programmers. At the beginning of their sourcecode
    they (naturally) don't have any BOOK objects. But the map of books is
    already filled. Maybe they even will not be allowed to add other books
    (the constructor taking enough arguments to create a fully defined BOOK
    may be private). So how do they make BOOK objects? I proposed a
    constructor taking a title that returns a copy of an existing book:

    BOOK tolkien("The Hobbit");

    If I understand Victor correctly, his point is that a constructor should
    create something new and not return something existing. I suppose he would
    prefer using a function like findByTitle() that returns an existing book.
    If findByTitle() is static, as Victor proposed, that would work for
    nameless objects:

    cout << BOOK::findByTitle("The Hobbit").author;

    But how do I create named objects? I don't expect to have a default
    constructor (is there a default book?). So the only way to create a named
    object would be to copy-construct from a nameless object returned by
    findByTitle():

    BOOK tolkien( findByTitle("The Hobbit") );


    > Plus, you still haven't explained what a LIBRARY is (nor why your
    > collection
    > of BOOKs is contained in a BOOK object instead of a LIBRARY object).


    O.k., forget about LIBRARY. I invented it quickly and it was a bad
    example. Objects of my second class contain a subset of by "books",
    LIBRARY would be more like a superset. I'll try to invent something better
    a few lines down :)
    My collection of BOOKs is NOT contained in any BOOK object. It's static,
    so it's contained in the class. I think that's not too bad -- each object
    contains a single book, the class has a collection of all my books.

    If my second class contains a subset of my books, maybe a good example
    could be BOOKSHELF or GENRE. Let's try GENRE. My only point here was, if
    GENRE has a method addBook() that takes a BOOK as an argument, then with
    the constructor I proposed I could say:

    GENRE fantasy;
    fantasy.addBook("The Hobbit");

    otherwise I have to say

    fantasy.addBook( findByTitle("The Hobbit") );

    I like that first form, but that's just personal preference.

    >> For named objects I think at least a copy-constructor is required, even
    >> when findByTitle is used instead of a constructor:
    >>
    >> BOOK tolkien( findByTitle("The Hobbit") );
    >>

    >
    > I don't understand what you mean when you say "even when findByTitle is
    > used
    > instead of a constructor". A copy-constructor takes a const reference
    > to an
    > existing object (a BOOK) and creates a new one based on that. It's
    > irrelevant how you obtained that reference.


    Victor wrote: "why do I need to construct another object from a single
    'title' when I already have one sitting in the map<string, BOOK>?" My
    point was: The objects in the map are nameless. If somebody wants a named
    BOOK object, he will need some kind of contructor to create it. Either the
    contructor taking a title, as I proposed, or a copy constructor as
    mentioned above.

    >> Also the constructor taking a title is somewhat convenient. Compare:
    >>
    >> cout << BOOK("The Hobbit").author;
    >> cout << BOOK::findByTitle("The Hobbit").author;

    >
    > Is findByTitle a static function??? Why are you specifying
    > BOOK::findByTitle, and not something like someBook.findByTitle? This
    > seems
    > to point tight back to the use of another class (LIBRARY) to hold the
    > collection instead of an individual BOOK.


    1. findByTitle() wasn't static in my first post. But I think Victor
    pointed out correctly that it should be.
    2. How do I construct your someBook?

    > Assuming that findByTitle returns a
    > reference to an existing BOOK object (does it?),

    Yes, it does.
    > then you might want to do this:
    >
    > BOOK& someOtherBook = someBook.findByTitle("The Hobbit");
    > cout << someOtherBook.author << endl;
    > cout << someOtherBook.price << endl;
    >
    > There's no construction going on here at all, and I only need the
    > findByTitle call once.
    >
    > (Or if findByTitle returns a pointer, then use a pointer instead of a
    > reference...but my point is the same.)


    I'm a bit reluctant to use pointers or references to objects in my map. I
    don't think that current implementations will ever reallocate memory as
    they grow. The nodes of the underlying tree have pointers to parent, left
    and right, so it's sufficient to manipulate those pointers during groth.
    But is this behavior guaranteed by any standard?

    How was someBook created? Maybe like this:

    BOOK someBook( findByTitle("Programming Perl") );

    Now does it make sense to say:

    someBook.findByTitle("The Hobbit"); ?

    I would prefer to use findByTitle() as a static function:

    BOOK::findByTitle("The Hobbit");

    > Without a more realistic sample of your code and the problem you face,
    > (especially showing the context in which you feel the need to use a newly
    > constructed object like that instead of a pointer or reference), I doubt
    > we can tell you any more than you already know.


    O.k.. I just thought that I might have overseen some very simple solution.

    Again, thank you for this discussion. If forced me to think again about
    some aspects of my design and that's always good!

    Wolfram
     
    Wolfram Humann, Sep 12, 2003
    #10
  11. "Wolfram Humann" <> wrote...
    > [...] At the beginning of their sourcecode
    > they (naturally) don't have any BOOK objects. But the map of books is
    > already filled. [...]


    Here is what I fail to understand. What is the map filled with
    if there are no BOOK objects? If you can answer that, you can
    probably give a better description of your problem. Try.

    Victor
     
    Victor Bazarov, Sep 14, 2003
    #11
  12. On Sun, 14 Sep 2003 03:56:53 GMT, Victor Bazarov <>
    wrote:

    > "Wolfram Humann" <> wrote...
    >> [...] At the beginning of their sourcecode
    >> they (naturally) don't have any BOOK objects. But the map of books is
    >> already filled. [...]

    >
    > Here is what I fail to understand. What is the map filled with
    > if there are no BOOK objects? If you can answer that, you can
    > probably give a better description of your problem. Try.
    >
    > Victor
    >


    How about this case: There's a static member

    BOOK::defineBook(const string& title, const string& author,
    const int pages, const double price);

    It is usually called at the beginning of the source-code. It uses a
    (private?) constructor to create BOOK objects and puts them into the map.
    So the objets are there but how can I access them? The key of the map is
    the title, so I think access should be by title. Suppose I know there is a
    BOOK in the map titled "The Hobbit". How do I create a BOOK object
    "tolkien" that refers to that book? My idea was:

    BOOK tolkien("The Hobbit");

    That requires a constructor taking a title that retrieves books form the
    map.

    O.K., I tried. Is it any clearer now? :)

    Wolfram
     
    Wolfram Humann, Sep 16, 2003
    #12
  13. Wolfram Humann

    Howard Guest

    "Wolfram Humann" <> wrote in message
    news:eek:prvds08c31udsjr@netnews...

    I still don't think that there is any reason to construct a new object at
    all, unless you are adding it to your map. If you're just inquiring for
    information about an existing book, then simply return a reference to one.
    If there is a chance that the book might not exist, then either throw an
    exception and handle it, or else return a pointer instead of a reference,
    and make it nil when the specified book doesn't exist. Regardless of
    whether you're getting a "named" variable or not, that's just the logical
    way of doing it. For example,:

    (using a returned reference, and trapping for the exception:)

    try
    {
    cout << BOOK::findByTitle("The Hobbit").author;
    cout << BOOL::findByTitle("The Hobbit").publisher;
    }
    catch(...)
    {
    // ...error? create and add a new one?
    }

    (very inefficient, since it looks up the book twice, but still there is no
    constructor being used),

    OR (better, in my opinion, using a returned pointer which *may* be nil)...

    BOOK* someBook = BOOK:findByTitle("The Hobbit");
    if (someBook)
    {
    cout << someBook->author;
    cout << someBook->publisher;
    }
    else
    {
    // ...error? create and add a new one?
    }

    This second design is just much more logical. But notice that in neither
    case is there any construction going on. If you need to add a book that is
    NOT in the map, then you'll already have all that info at hand, and can
    simply call the constructor that takes the whole set of required information
    as parameters, with no need to look up whether a book exists or not during
    construction, because you've already checked fact that via the static
    findByTitle function.

    Hope this helps..

    -Howard
     
    Howard, Sep 16, 2003
    #13
  14. Wolfram Humann wrote:
    >
    > On Sun, 14 Sep 2003 03:56:53 GMT, Victor Bazarov <>
    > wrote:
    >
    > > "Wolfram Humann" <> wrote...
    > >> [...] At the beginning of their sourcecode
    > >> they (naturally) don't have any BOOK objects. But the map of books is
    > >> already filled. [...]

    > >
    > > Here is what I fail to understand. What is the map filled with
    > > if there are no BOOK objects? If you can answer that, you can
    > > probably give a better description of your problem. Try.
    > >
    > > Victor
    > >

    >
    > How about this case: There's a static member
    >
    > BOOK::defineBook(const string& title, const string& author,
    > const int pages, const double price);
    >
    > It is usually called at the beginning of the source-code. It uses a
    > (private?) constructor to create BOOK objects and puts them into the map.
    > So the objets are there but how can I access them? The key of the map is
    > the title, so I think access should be by title. Suppose I know there is a
    > BOOK in the map titled "The Hobbit". How do I create a BOOK object
    > "tolkien" that refers to that book? My idea was:
    >
    > BOOK tolkien("The Hobbit");
    >
    > That requires a constructor taking a title that retrieves books form the
    > map.
    >
    > O.K., I tried. Is it any clearer now? :)


    You still have not figured out, that you have a design error.
    A single book is not a library of books. Nor does one single
    book contain the whole library.

    There should be 2 classes:
    BOOK and LIBRARY

    --
    Karl Heinz Buchegger
     
    Karl Heinz Buchegger, Sep 17, 2003
    #14
  15. On 16 Sep 2003 19:00:07 GMT, Howard <> wrote:

    > If you're just inquiring for information about an existing book,
    > then simply return a reference to one [...], or else return a
    > pointer instead of a reference, and make it nil when the
    > specified book doesn't exist.


    I see your point and I agree that this is a clean solution. Two remarks:

    1. I still could not find any statement in the standard that
    references/pointers to map entries will always remain valid when the map
    grows/shrinks. As I said, I don't think the current implementation of a
    map will reallocate memory (like e.g. the vector does) but I don't want to
    rely on this unless the standard defines that it's illegal for a map to
    reallocate memory for its entries.

    2. Using references or pointes may be more logical than creating
    "redundant" objects but at least for my current project I won't be able to
    do this. My code has to remain consistent with existing code.

    Wolfram
     
    Wolfram Humann, Sep 17, 2003
    #15
  16. Wolfram Humann

    Howard Guest

    "Wolfram Humann" <> wrote in message
    news:eek:prvmzg6x01udsjr@netnews...
    > On 16 Sep 2003 19:00:07 GMT, Howard <> wrote:
    >
    > > If you're just inquiring for information about an existing book,
    > > then simply return a reference to one [...], or else return a
    > > pointer instead of a reference, and make it nil when the
    > > specified book doesn't exist.

    >
    > I see your point and I agree that this is a clean solution. Two remarks:
    >
    > 1. I still could not find any statement in the standard that
    > references/pointers to map entries will always remain valid when the map
    > grows/shrinks. As I said, I don't think the current implementation of a
    > map will reallocate memory (like e.g. the vector does) but I don't want to
    > rely on this unless the standard defines that it's illegal for a map to
    > reallocate memory for its entries.
    >
    > 2. Using references or pointes may be more logical than creating
    > "redundant" objects but at least for my current project I won't be able to
    > do this. My code has to remain consistent with existing code.
    >
    > Wolfram


    Well, then just write a proper copy-constructor. Let findByTitle return a
    const reference (throwing an exception if not found), and pass its result as
    the parameter for the constructor, like this:

    try
    {
    BOOK aBook(findByTitle("The Hobbit"));
    }
    catch(...)
    {
    //...error?
    }

    or

    try
    {
    const BOOK& refBook = BOOK::findByTitle("The Hobbit");
    BOOK* pPook = new BOOK(refBook);
    }
    catch(...)
    {
    // ...error?
    }

    -Howard
     
    Howard, Sep 17, 2003
    #16
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    3
    Views:
    864
    Peter_Julian
    Oct 10, 2005
  2. Spoon
    Replies:
    7
    Views:
    419
    John Carson
    Dec 31, 2006
  3. Javier
    Replies:
    2
    Views:
    585
    James Kanze
    Sep 4, 2007
  4. fungus
    Replies:
    13
    Views:
    902
    fungus
    Oct 31, 2008
  5. aaragon
    Replies:
    2
    Views:
    626
    James Kanze
    Nov 2, 2008
Loading...

Share This Page