hqt
hqt

Reputation: 30284

C++: different result when assign constant object to non constant object

I have a class with two setter. One, the parameter is constant, and one is not.

class  Author
{
  string name;
  Book* book;
public:
  void setName(const string& name) { this->name = name; }  // no error
  void setBook(const Book* book) { this->book = book; } // error: value of const Book* cannot assign to Book*
}

My question is: why at setName method, I can make parameter constant with no error, but not in setBook.

Thanks :)

Upvotes: 0

Views: 156

Answers (3)

Steve Jessop
Steve Jessop

Reputation: 279305

Suppose you could do it, then you could write code like:

// definition of Book
struct Book {
    int pages;
}

// inside Author, member function
void setBook(const Book* abook) { 
    this->book = abook;
    this->book->pages = 1; // modify the object pointed to by abook
}

// calling code that uses Author class
const Book b = {0}; // a const object
myAuthor->setBook(&b); // modifies a const object

The point of the const system is to prevent you from modifying a const object unless your code includes a cast (that removes const). Therefore it forbids you from assigning a value of type pointer-to-const, to a variable whose type is pointer-to-non-const.

Upvotes: 1

Agent_L
Agent_L

Reputation: 5421

const Book* is a pointer to (const Book), not (const pointer to) Book. (I believe you expected the later).

You should use a typedefed pointer-type to avoid such errors. Look how it's done in windows.h:

typedef ULONG *PULONG;

This way there's no confusion. My advice: write typedef Book *PBook; right after class Book declaration and never-ever type "Book*" in actual code.

Upvotes: 2

Andre Holzner
Andre Holzner

Reputation: 18695

because you would be able to modify the object *book points to after assigning it to this->book, thus circumventing the constness of the argument.

(you'd have to explicitly cast it to a pointer to a non-const object)

In other words,

  • the declaration setBook(const Book* book) means that the object pointed to by book will not be modified (that's a 'promise' to the calling function).
  • The field this->book is however declared in a way that you can easily modify the object pointed to by it.

Through the assignment this->book from the function argument book you would be able to later on modify the object originally pointed to by the function argument book.

Upvotes: 4

Related Questions