Commit 941226ba authored by droger's avatar droger Committed by Commit bot

Allow copying scoped_nsobject of different type.

This code was leading to a crash:
scoped_nsobject<MyClass> a([[MyClass alloc] init]);
scoped_nsobject<NSObject> b(a);

Because |a| is converted to raw pointer, and |b| is constructed with the
raw pointer, without calling retain. This creates a subtle crash later on
when the scoped_nsobject are destroyed.

This code however, was not crashing:
scoped_nsobject<MyClass> b(a);
Because in that case the copy constructor is used.

This was somewhat inconsistent and bug prone, especially if the type of
|a| is changed. In that case the type of |b| must be changed at the same
time, or it causes a crash.

This CL introduces a new constructor for the scoped_nsobject variants
that allows passing a scoped_nsobject of a different type.
It is consistent with scoped_refptr which also has this constructor.

Review URL: https://codereview.chromium.org/848033006

Cr-Commit-Position: refs/heads/master@{#311487}
parent f6ade006
...@@ -40,6 +40,11 @@ class scoped_nsprotocol { ...@@ -40,6 +40,11 @@ class scoped_nsprotocol {
: object_([that.object_ retain]) { : object_([that.object_ retain]) {
} }
template <typename NSU>
scoped_nsprotocol(const scoped_nsprotocol<NSU>& that)
: object_([that.get() retain]) {
}
~scoped_nsprotocol() { ~scoped_nsprotocol() {
[object_ release]; [object_ release];
} }
...@@ -119,6 +124,11 @@ class scoped_nsobject : public scoped_nsprotocol<NST*> { ...@@ -119,6 +124,11 @@ class scoped_nsobject : public scoped_nsprotocol<NST*> {
: scoped_nsprotocol<NST*>(that) { : scoped_nsprotocol<NST*>(that) {
} }
template<typename NSU>
scoped_nsobject(const scoped_nsobject<NSU>& that)
: scoped_nsprotocol<NST*>(that) {
}
scoped_nsobject& operator=(const scoped_nsobject<NST>& that) { scoped_nsobject& operator=(const scoped_nsobject<NST>& that) {
scoped_nsprotocol<NST*>::operator=(that); scoped_nsprotocol<NST*>::operator=(that);
return *this; return *this;
...@@ -135,6 +145,11 @@ class scoped_nsobject<id> : public scoped_nsprotocol<id> { ...@@ -135,6 +145,11 @@ class scoped_nsobject<id> : public scoped_nsprotocol<id> {
: scoped_nsprotocol<id>(that) { : scoped_nsprotocol<id>(that) {
} }
template<typename NSU>
scoped_nsobject(const scoped_nsobject<NSU>& that)
: scoped_nsprotocol<id>(that) {
}
scoped_nsobject& operator=(const scoped_nsobject<id>& that) { scoped_nsobject& operator=(const scoped_nsobject<id>& that) {
scoped_nsprotocol<id>::operator=(that); scoped_nsprotocol<id>::operator=(that);
return *this; return *this;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment