Let's say I have a class
class Object
{
public:
Object(int i) : num(i) {};
int getNum() const { return num; }
private:
int num;
};
Now, if I try to do this
Object obj{ 1 };
Object obj2{ 2 };
Object obj3 = obj + obj2; //This is wrong
This is illegal: 'Object' does not define this operator or a conversion to a type acceptable to the predefined operator
.
Adding Object operator+(const Object&) = delete;
doesn't really change anything, except for the error message: 'Object Object::operator +(const Object &)': attempting to reference a deleted function
.
Is the delete
only needed for operators that have an implicit declaration (like assignment operator and copy/move constructor) or does it change anything else in my case?
delete is used for one single pointer and delete[] is used for deleting an array through a pointer. This might help you to understand better.
The delete operator removes a given property from an object. On successful deletion, it will return true , else false will be returned.
What is the difference between delete and delete[] in C++? Explanation: delete is used to delete a single object initiated using new keyword whereas delete[] is used to delete a group of objects initiated with the new operator. 4.
Using the delete operator on an object deallocates its memory.
Is the delete only needed for operators that have an implicit declaration (like assignment operator and copy/move constructor) or does it change anything else in my case?
No and no. Your case is merely too simple for any such difference to matter.
= delete
serves two purposes:
1: It forcibly removes functions which would (potentially) otherwise be there. Namely, the special member functions.
2: It specifies that a function with that signature cannot be called. This is essentially a generalization of #1.
The archetypal example of the latter is for preventing implicit conversion of function arguments. If you do this:
void foo(float val);
void foo(int) = delete;
You can no longer call foo(5)
; you must use foo(5.f)
. Why? Because the compiler will see the second overload, see that it matches the call the best, and then immediately fail because the function is deleted.
This is sometimes done like this as well:
void foo(float val);
template<typename T> void foo(T&&) = delete;
This ensures that you can only call it with an actual float
. No type which is implicitly convertible from float
will work.
The anwer by @NicolBolas is perfectly acceptable. Here's another example to illustrate that sometimes it's not enough not to declare/define a function because someone else does (such as the compiler generated special member functions) and your code can call it (e.g. through implicit constructors or conversion operators).
#include <iostream>
// your code
struct Base {};
// some teammate
struct Wrap
{
/* implicit */ Wrap(Base const& b) {}
};
void fun(Wrap const&) { std::cout << __PRETTY_FUNCTION__ << '\n'; }
// client code
int main()
{
Base b;
fun(b); // oops, probably didn't intend to call fun(Wrap const&)
}
Live Example that outputs void fun(const Wrap &)
.
Now in the old days pre-C++11, you could declare but not define
void fun(Base const&); // no definition provided
Live Example that outputs the linker error
main.cpp:(.text+0x36): undefined reference to 'fun(Base const&)'
From C++11 onwards, you can explicitly delete the same function
void fun(Base const&) = delete; // C++11 onwards
Live Example that outputs the compiler error (which is much more informative than the previous linker error)
main.cpp:20:5: error: call to deleted function 'fun'
fun(b); // oops, probably didn't intend to call fun(Wrap const&)
^~~
main.cpp:6:6: note: candidate function has been explicitly deleted
void fun(Base const&) = delete; // C++11 onwards
^
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With