0

for optimization purposes I am writing a class in which the copy operator passes the internals of the class by reference.

However I want to be able to write two copy operators, one that accepts const values and can only be called by a const object and a non-const variant that then can call non-const methods.

IE I would like something similar to...

myClass& operator= (const myClass& copy_to, const myClass& copy_from);
myClass& operator= (myClass& copy_to, myClass& copy_from);

However in C++ the copy operator must be non-static and can only accept 1 parameter. How can I ensure that the copy operator accepting a const parameter only be called from a const calling object?

If there are any issues with my question please comment so I may improve*

  • 1
    Why do you think you need an assignment operator that has a non-const reference parameter? The *single* parameter typically is a reference to the source object to copy from, so the source is *read-only*. – zett42 Jul 04 '17 at 20:40
  • `const myClass copy_to&` seems strange... – Jarod42 Jul 04 '17 at 20:41
  • According to [What are the basic rules and idioms for operator overloading?](https://stackoverflow.com/questions/4421706/what-are-the-basic-rules-and-idioms-for-operator-overloading) what you are looking for is `myClass& myClass::operator= (const myClass & copy_from);` This will be invoked on the object to be copied to. Also watch where you put the `&`. Very important to have that placed correctly. – user4581301 Jul 04 '17 at 20:53
  • @zett42 As noted I do not plan on copying the data as it would be very inefficient. The class is essentially a wrapper for the internal data. I am passing the data by a pointer. So the copy_to object may still manipulate (and change) the data even if the original copy_from is const. – Joseph Franciscus Jul 04 '17 at 20:55
  • @user4581301 The question is not how to write a copy operator. The problems lies in finding a way to ensure that the calling object (copy_to) is constant if the parameter object is constant. Likewise if the parameter is non-const the calling object maybe either const or mutable. – Joseph Franciscus Jul 04 '17 at 20:59
  • Clearly I am missing something. If you have a constant you can't change it. That's the point. – user4581301 Jul 04 '17 at 21:00
  • Next nasty is if you have two objects pointing to the same internals, you will either have a memory leak or a very bad day when the destructors run. `std::shared_ptr` may help you here. – user4581301 Jul 04 '17 at 21:02
  • @user4581301 if in my object I have `someData* data` and in my `copy constructor` I make `data`of `copy_to` point to the `data` of `copy_from` I can modify data from within `copy_to` I do not need a shared pointer I have already written an appropriate destructor, when cases such as this arise. – Joseph Franciscus Jul 04 '17 at 21:11
  • Do you want something like [that](https://ideone.com/8Bq2eR). – Jarod42 Jul 04 '17 at 21:36

1 Answers1

0

It's important to respect the concept. The user doesn't expect a modified source object after a copy operation. This is a postcondition to the concept CopyAssignable.

t = v //postcondition: The value of v is unchanged. 

The const modifier, for the source parameter, explicits this requirement to the user: a read-only object.

Maybe a move ctor ou move assignment operator(MoveAssignable) can serve you. If not, I think so it's a good idea to leave out the copy concept here.

Cosme
  • 191
  • 2
  • 6
  • This is why I am trying to ensure that the copy/move operator with a const parameter can only be called from a const calling object to ensure that the copy_from object will not be changed. – Joseph Franciscus Jul 04 '17 at 21:21
  • Do you care about the object bound to `copy_from` after your non-const operation? – Cosme Jul 04 '17 at 21:41
  • IMHO, you don't need to ensure this for a copy operation because the source must be a `const` and a lvalue const ref. can be bound to a const and non-const lvalue ref. as also a rvalue. It's a no brainer decision to the copy operation. – Cosme Jul 04 '17 at 21:47
  • 1
    Thanks, I looked into movement operator/assignment and seems like a good solution to my problem. Voting you as best answer for now. – Joseph Franciscus Jul 05 '17 at 23:47