-1

Okay, basically I've searched all over the internet but I've found nothing that really explained it well enough or at all, for my situation at least.

Let's just say we have a class named book. We add two objects to that class (each object having a title and release date (the release date is written as day,month,year).

Okay, we shall name those two objects BOOKONE and BOOKTWO, respectively. I want to write a function that receives these following parameters and modifies the content of respective object.

modify(BOOKONE, 12, 5, 2017)

This function would modify the release date of BOOKONE from its current date to the one there. Okay, basically I don't need the contents of the function, but I need to know how I can give the name of an object as a parameter to that function. I need to give it as a parameter. I can't just create a function and call it like BOOKOKE.modify.

I have literally no idea how that would look like.

Here's the main issue, since I know I can be bad at explaining stuff:

modify(?????, int x, int y, int z)

nsnro
  • 5
  • 2
  • Why can't you give an object as a parameter to a function? `void modify(book theBook, int x, int y, int z)` works just fine. Or `void modify(book &theBook, int x, int y, int z)` if you want to pass a reference instead of a copy. – user253751 Jul 08 '16 at 00:16
  • 2
    The short answer here: write your own code to do it. C++ [does not have reflection](https://en.wikipedia.org/wiki/Reflection_(computer_programming)). It's up to you to implement your own mechanism for mapping opaque strings (or identifiers of some other nature), into discrete objects. – Sam Varshavchik Jul 08 '16 at 00:19
  • Before you can find an answer through searching, you'll need to work out how to properly describe your requirement! I suggest taking this into a chatroom for one-on-one mentoring; it is not suitable for a Q&A database. – Lightness Races in Orbit Jul 08 '16 at 00:54
  • If you don't want to write C++ pick a different language. If you do then write a modify method and call `BOOKONE.modify(x, y, z)` – stark Jul 08 '16 at 00:55
  • do you really want to do something like this ? void modify(book &b, x,y,z) { b.modify(x,y,z); } – Jay Kumar R Jul 08 '16 at 00:59
  • Functions take parameters: their types and (usually) their names. Your terminology may be the source of your confusion. – jonspaceharper Jul 08 '16 at 02:39
  • okay. Less okays please. Okay? Okay. – bolov Jul 08 '16 at 18:13

1 Answers1

3

You could make a std::map of books indexed by their name.

std::map<std::string, book> books;

And then

bool modify(const std::string &name, int day, int month, int year)
{
    books[name].setreleasedate(day, month, year);
    return true; // always succeeds
}

This will find thenamed book in books, or automatically create the named book if it does not exist, and then invoke the book's method for setting the release date.

If you do not want books to be created on the fly, your options are to use std::map::at or std::map::find

std::map::at version:

bool modify(const std::string &name, int day, int month, int year)
{
    try
    {
        books.at(name).setreleasedate(day, month, year);
        return true;
    }
    catch(std::out_of_range & ) // did not find named book
    {
        return false;
    }
}

This has a significant performance penalty in the handling of the exception if unknown books are frequently looked up--as in unknown books are not exceptional. As is hinted by the name, exceptions should only be used for exceptional events. More on why can be read here, if interested: Are Exceptions in C++ really slow

This also requires C++11 standard support to get the at method.

std::map::find version:

bool modify(const std::string &name, int day, int month, int year)
{
    std::map<std::string, book>::iterator found; // could be auto found if C++11 is enabled
    found = books.find(name)
    if (found != books.end()) // if search ended before the end of books
    {            
        found->setreleasedate(day, month, year);
        return true;
    }
    else // did not find named book
    {
        return false;
    }
}

This version requires a bit more code and adds nigh insignificant cost all the time, but does not have a significant penalty for the failure case.

Also supported by all C++ back to the beginning of standardization. Unless you're developing with Turbo C++ there should be no surprises.

Community
  • 1
  • 1
user4581301
  • 33,082
  • 7
  • 33
  • 54
  • 1
    If `name` does not exist in `books`, accessing `books[name]` will create a new `book` object. If you don't want that to happen, use `books.find(name)` instead: `std::map::iterator iter = books.find(name); if (iter != books.end()) iter.second.setreleasedate(day, month, year);` – Remy Lebeau Jul 08 '16 at 01:47