Constructor for a class that takes in another class as parameters

I'm trying to make a class called Book that stores the Book title and Date. Paratmeter for title is simple enough, but I don't know how to pass in a Date as a paramter for the Books constructor. I'm also not sure if string title is the only member variable I'll need. I'm new to this so if theres an example or method of doing this I'd like to know so I can read up on it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Date{
    private:
        int month;
        int day;
        int year;

    public:
        Date(int x, int y, int z): day(x), month(y), year(z){}

        int get_month() const {return month;}
        int get_day() const {return day;}
        int get_year() const {return year;}
};

class Book{
    private:
        string title;
        //Create Date?

    public:
        Book(string x, Data& obj){
            title = x;
        }
        string get_title() const {return title;}
};

int main()
{
 const Book children_book("Hunger Games", Date{18, 10, 2001});
}
Last edited on
It looks ok, but this:
 
        Book(string x, Data& obj){


should be this:
 
        Book(string x, Data obj){

I'd use const refs here...

Book(const string& x, const Data& obj){

As the Date class is so small it is cheap enough to pass by value, as kbw suggests.

But string should usually be passed by const ref. Passing a std::string by value only makes sense if you want the function to be able to change the copy of the string it receives.

As a general rule I pass built-in types by value and class types by const ref, whatever their size (for consistency.) I only break this rule when there are performance considerations.

Andy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
using namespace std;

class Date{
    private:
        int month;
        int day;
        int year;

    public:
        // The order of variables in the initializer list should match
        // that of the declarations in the class body (so swapped day
        // and month)
        // And (m, d, y make more sense than x, y, x?)
        Date(int m, int d, int y): month(m), day(d), year(y){}

        int get_month() const {return month;}
        int get_day() const {return day;}
        int get_year() const {return year;}
};

class Book{
    private:
        string title;
        Date   due_date; // or published date, etc?

    public:
        // use const ref for string and Date
        // (and corrected typo: Data -> Date)
        Book(const string& x, const Date& date): title(x), due_date(date){
            //title = x; use constructor initializer list, as you did in Date
        }
        string get_title() const {return title;}
        Date get_due_date() const {return due_date;} // new method
};

int main(){
    const Book children_book("Hunger Games", Date{18, 10, 2001});

    cout << "title    = " << children_book.get_title() << "\n"
         << "due date = " << children_book.get_due_date().get_month() << "/"
                          << children_book.get_due_date().get_day()   << "/"
                          << children_book.get_due_date().get_year()  << "\n"
         << "\n";
    // neater to provide operator<< overload for Date...
 
    return 0;
}
Last edited on
@Extreme112

Presumably "Data" should actually read "Date"?

It looks as though you already know how to use the initialisation list in a constructor, so what's wrong with having a Date data member, and initialising it that way?

@kbw

Why? There's nothing wrong with passing the date as a reference, rather than by value, as long as the Book class ultimately makes its own persistent copy of the date, rather than keeping a reference that could end up dangling.

Of course, it would make more sense for it to be a const reference.
Actually, a non-const ref for Date is not suitable here as you want this to work:

const Book children_book("Hunger Games", Date{18, 10, 2001});

This requires the Date parameter to be passed by either value or const ref.

If you use a (non-const ref) then you'd need to use this form for it to work:

1
2
Date due_date{18, 10, 2001};
const Book children_book("Hunger Games", due_date);

(Visual Studio's C++ compiler -- with language extensions enabled -- let's you get away with it, with

warning C4239: nonstandard extension used : 'argument' : conversion from 'Date' to 'Date &'
1>          A non-const reference may only be bound to an lvalue"

but it's an error for GCC.)

With C++11 you could also has an rvalue ref, but don't see any value in doing so here.

Book(const string& x, Data&& obj){

Andy
Last edited on
Thanks for the help guys. Now I'm trying to pass in a vector of authors with the author class below. How can I return/display the Author objects elements like how Date objects and member functions were accessed.
1
2
3
4
5
6
7
8
9
10
11
class Author{

    private:
        string first_name;
        string last_name;

    public:
        Author(const string& q, const string& r): first_name(q), last_name(r){}
        string get_first_name() const {return first_name;}
        string get_last_name() const {return last_name;}
};

I've edited the Book class to look like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
class Book{
    private:
        string title;
        vector<Author> author_mem;
        Date pub_date;

    public:
        Book(const string& x, const vector<Author>& author_fn, const Date& date):title(x), author_mem(author_fn), pub_date(date){}

        vector<Author> get_author_list() const {return author_mem;}
        string get_title() const {return title;}
        Date get_pub_date()const {return pub_date;}
};

This complies however I don't know how to access the individual Author objects like how Andy was able to access the member functions of the Date object.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int main()
{
    const Date pub_date(1,2,2003);
    const Author alice("Alice", "Kray");
    const vector<Author> authors = {alice};

    const Book children_book("Kids Tales", authors, pub_date);

    //My interpretation of the expression below is that we access the Book object children_book, 
//then access the Date object of the book via get_pub_date(), the access its member function get_month()
    cout << children_book.get_pub_date().get_month();

    //So below I try to go through the same as the above process. Acess children-book, 
   //then access the vector of authors, get the first element of Author to acess the Author member //functions.  
    cout << children_book.get_author_list().at(0).get_first_name;
}


EDIT: Firgured it out. Frogot parenthesis at get_first_name.
Last edited on
Topic archived. No new replies allowed.